Stampa la tabella ASCII


28

L'attività consiste nel visualizzare n caratteri della tabella ASCII .

È possibile scrivere una funzione (o un programma che accetta l'argomento come parametro, anche STDIN è consentito) che accetta un parametro n , che sarà l'indice dell'ultimo carattere da stampare.

Il compito è abbastanza semplice, quindi ad esempio ecco una possibile implementazione in Python 2.7:

(lambda n:map(chr, range(n)))(256)

Come ho già detto, è un compito semplice. Quindi questo è code-golf e vince il codice più corto!

MODIFICARE

Come alcuni di voi hanno sottolineato questo codice non stampa il risultato. È solo un esempio poiché potrei avere difficoltà a spiegare il problema in inglese ;-).

EDIT2

Sentiti libero di pubblicare la risposta in qualsiasi linguaggio di programmazione, anche se non è il codice più breve. Forse ci sono alcune implementazioni interessanti là fuori!

Edit3

Risolto l'esempio in modo che stampasse il risultato.


1. Deve essere una funzione? 2. In base al codice di riferimento, n sarebbe il primo carattere che non viene stampato.
Dennis,

2
In realtà il codice di riferimento non stampa nulla. Restituisce semplicemente un elenco di caratteri e consente al REPL di fare tutto ciò che vuole con il risultato.
arte

1
Qualcuno può spiegare il downvote? Mi dispiace se il mio inglese non è così buono. Se c'è qualcosa di poco chiaro nella domanda, per favore dimmelo.
oopbase,

1
for x in range(input()):print chr(x)Stamperebbe effettivamente i caratteri, se si desidera modificare il proprio esempio.
FryAmTheEggman,

2
nota [i for i in range(n)]è abbastanza simile arange(n)
njzk2,

Risposte:


19

CJam, 4 byte

ric,

Programma completo che legge da STDIN (campo di input nell'interprete online ).

Questo si esegue semplicemente range(chr(int(input()))), sfruttando il fatto che ,dà un ritorno a una matrice di caratteri se il suo argomento è un personaggio.

Chiamo dibs on c,(2 byte), nel caso in cui si supponga che l'assunzione sia già nello stack.


Devi specificare qualche input? Il corridore online emette semplicemente il codice stesso.
arte

12
@manatwork: solo un secondo. Devi sbrigarti quando pubblichi questi ...;)
Dennis,

Sono un po 'confuso da questo. Il carattere a 0 (aka 0c) impedisce che qualsiasi altra cosa venga stampata dopo di esso. ric, (sembra funzionare bene. Ciò significa che il codice non funziona.
Kaine,

1
@kaine: Internet Explorer è scritto in C ++, che non utilizza stringhe con terminazione null. In base a ciò , i caratteri null sono errori di analisi in HTML 5; il browser deve sostituirlo con un o interrompere l'elaborazione del documento.
Dennis,

4
Tieni presente che devi inserire un valore sufficientemente grande n, poiché le prime decine di caratteri ASCII sono caratteri non stampabili. Curiosità: questo programma genera anche la tabella Unicode, ad esempio n = 9999
Sanchises

25

brainfuck - 169 146 142 byte

-[+>+[+<]>+]>+>>,[>,]<[<]<[->>[->]<[<]<]>>>[[<[-<+<+<+>>>]+++++++++[<[-<+>]<<[-<+>>>+<<]<[->+<]>>>>-]]<,<<,>[->>>+<<<]>>>---------->]<-[->.+<]

limitazioni:

  • EOF deve essere 0
  • Richiede celle di avvolgimento a 8 bit
  • A causa di ^, le mod sono inserite da 256

Non la risposta più breve qui, ma hey, brainfuck! Questa sarebbe una vera e propria sfida di brainfuck, fatta eccezione per il fatto che richiede input leggibili dall'uomo senza garantire il numero di cifre. Avrei potuto richiedere l'input per avere zero iniziali per renderlo lungo 3 caratteri, ma che divertimento è? : D Un grosso problema con l'input in questo modo è che l'unica struttura di ramificazione o loop di brainfuck controlla se la cella corrente è zero o no. Quando l'input può contenere zero, il codice può prendere rami che non dovrebbe prendere. Per risolvere questo problema, memorizzo ogni cifra di input più 1 , quindi sottraggo l'eccesso nell'ultimo secondo possibile. In questo modo, so sempre dove sono i miei zero.

Ho detto che sarebbe stata una grande sfida per il cervello senza dover analizzare l'input. Perché? Bene, facciamo finta che non prendiamo un input numerico. Diremo che la sfida è "Dato un byte di input, output tutti i caratteri ASCII al di sotto di quel byte". Ecco quale sarebbe la mia risposta:


brainfuck - 8 byte

,[->.+<]

È abbastanza una differenza! Il vero programma utilizza 135 istruzioni per raccogliere l'input (oltre il 95% del programma!), Solo perché è un essere umano che lo digita. Memorizzare il numero come un byte e dare che a me, e richiede solo uno.

(Fatto curioso: se hai capito l'ipotetico programma, allora congratulazioni! Comprendi il brainfuck nella sua interezza. L'intera lingua ha solo otto comandi e quel programma sembra usarli esattamente una volta.)

Spiegazione

-[+>+[+<]>+]>+               abuse 8 bit wrapping to put 47 in cell 4

>>,[>,]                      starting in cell 6; get each character of input

<[<]<[->>[->]<[<]<]          subtract the value of cell 4 from each input character
                             '0' has an ascii value of 47 so subtracting 47 from each
                             digit gives you that digit's value plus 1

>>>[                         if the number is in more than one cell
                             (when the program first starts this means "if the input has
                             more than one digit")

[<[-<+<+<+>>>]               copy first input cell to 3 new cells

+++++++++[<[-<+>]<<          do some fancy addition magic to multiply that value by 10
[-<+>>>+<<]<[->+<]>>>>-]]

<,<<,>                       clean up a bit (abusing comma to set cells to 0)

[->>>+<<<]>>>                add the value to the next cell of input

----------                   because we multiplied (the digit plus 1) by 10; the answer
                             is 10 too high; so subtract 10

>]                           if the input is still in multiple cells; do the song and
                             dance again (multiply by 10; add to next cell; subtract 10)

<-                           we never got a chance to fix the final digit; so it's still 1
                             too high

               ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
               ;;         we have now finished processing input         ;;
               ;;     the tape is empty except for the current cell     ;;
               ;;  the current cell contains the number that was input  ;;
               ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[                            while the cell containing input != 0

-                            subtract 1 from it

>.+                          go a cell to the right; output that cell; then add 1

<]                           repeat

Bello! Sicuramente +1 per lo sforzo :-)
oopbase

1
È possibile salvare alcuni byte sulla parte in uscita: >[-]<[->.+<]impostare la cella accanto alla cella corrente su 0, quindi contare la cella corrente aumentando la cella accanto ad essa e contemporaneamente stampando il valore.
Shujal,

@shu Questo è un punto eccellente! Non ci ho pensato affatto. Oltre ad essere più breve, risolve il problema che ho avuto con soffocamento su ingressi di grandi dimensioni ed è probabilmente più veloce! Grazie :)
undergroundmonorail,

Sì, ora è molto, molto più veloce. Inoltre non avevo bisogno della >[-]<parte perché ero già accanto a una cella vuota. :)
undergroundmonorail


12

Pyth , 4 byte

VQCN

Fondamentalmente una traduzione del programma Python 3:

for N in range(eval(input())):print(chr(N))

11

Befunge 93 - 23 21

&> :#v_,>:#,_@
 ^-1:<

Befunge 93 - 15 13 (da Ingo Bürk)

Questo stampa l'elenco al contrario, ma OP ha detto solo che dobbiamo stampare i primi ncaratteri, non che deve essere in ordine.

&>::>v
@^-1,_

Potrebbe non essere più giocabile a golf senza passare a Befunge98 (per l'operatore ";", vedere la risposta di @ Kasran )

Provalo qui:


Spero non ti dispiaccia che ho usato un interprete in linea da qui :)
Ingo Bürk,

La domanda non afferma che dobbiamo stamparlo in qualsiasi ordine, quindi questo è più corto di cinque byte: &> #- #1:# :#,_@(lo stampa semplicemente al contrario)
Ingo Bürk,

Ho rasato altri byte per un totale di 15. A causa delle nuove righe, lo modificherò nel tuo post.
Ingo Bürk,

Ben giocato sul golf extra :) Per quanto riguarda l'interprete in linea, non sapevo che ce n'era uno. È fantastico, grazie :)
Karhell,

L'interprete è nuovo dalla sfida collegata. Ho pensato di usarlo quando ho visto la tua risposta. :)
Ingo Bürk,

8

Java, 151 128 77 62 56 byte

Prima prova a giocare a golf.

void f(int n){for(char i=0;++i<=n;System.out.print(i));}

Uso:

import java.util.Scanner;
class A {

    public static void main(String[] a) {
        int num = new Scanner(System.in).nextInt();
        new A().f(num);
    }

    void f(int n) {
        for (char i = 0; ++i <= n; System.out.print(i));
    }
}

Grazie a @Shujal, @flawr, @Ingo Bürk e @Loovjo per la grave riduzione dei byte.


1
È possibile salvare alcuni caratteri dichiarando l'int durante l'apertura dello scanner: int i,n=new Scanner(...e cambiando il ciclo in for(;++i<n;). Inoltre, non è necessario invocare Character.toString. Puoi semplicemente alimentare System.out un valore char e lo produrrà felicemente.
Shujal,

1
La sfida consente l'uso del tuo acome input. E penso che puoi accorciare il forciclo abusando della posizione di incremento come corpo del ciclo: for(;++i<n;System.out.print((char)i));(ma potresti dover cambiare l'inizializzazione o il valore finale di + - 1)
flawr

1
Ti è permesso scrivere una funzione, quindi non c'è bisogno di un'intera classe e tutto il resto.
Ingo Bürk,

1
@RodolfoDias Sei sicuro? Ovviamente, ++i<n+1dovrebbe essere equivalente a ++i<=n. Nota l'interno =, comunque! Salva solo un byte. Per me funziona.
Ingo Bürk,

1
Quindi arriviamo a void f(int n){int i=0;for(;++i<=n;System.out.print((char)i));}62 byte. Almeno non vedo più il golf adesso. :)
Ingo Bürk,

6

APL, 5

⎕UCS⍳

Esempio di utilizzo:

⎕UCS⍳256

1
Non devi fare un dfn. Solo ⎕UCS⍳ funzionerebbe bene. Quindi 5 personaggi
Moris Zucca,

1
Non è necessario supportare punti di codice superiori a 127. Solo ↑ ⎕AV funzionerebbe bene. Quindi 4 caratteri
Adám

6

JavaScript, ES6 - 52 58 56 53 44 42 byte

n=>String.fromCharCode(...Array(n).keys())

Incollalo nella console di Firefox. Esegui come f(NUM).

Ho dovuto allungarlo perché il primo non ha accettato correttamente l'input.

Giù 3, grazie edc65! Fino a 44 grazie a Swivel!


1
Questo in realtà non gestisce né parametri né input.
arte

Basta cambiare il 70 con un numero diverso; questo è l'input.
Scimonster,

Va bene, l'ho aggiornato per ricevere input, al costo di 6 byte.
Scimonster,

3
-2: f = n => [... Array (n)]. Map ((v, i) => String.fromCharCode (i))
edc65,

2
44 personaggi! f=n=>String.fromCharCode(...Array(n).keys())
Girare il

6

Haskell, 17 23 byte

flip take['\0'..]

Non sono sicuro se sia possibile fare di meglio senza importazioni.

modificare

La mia prima soluzione non ha effettivamente stampato il risultato, quindi consenti altri 6 caratteri per quello:

print.flip take['\0'..]

Inoltre, non più breve (25 caratteri con la stampa, 19 senza), ma un approccio alternativo interessante (richiede 'Elenco dati', però):

print.((inits['\0'..])!!)

Questo in realtà non stampa il risultato.
nyuszika7h

@ nyuszika7h ora lo fa
John Dvorak,

(`take`['\0'..])salva un byte.
Laikoni,

4

Utilità comuni Bash + BSD, 9 byte

jot -c $1

GNU cc, 20 byte

?sc_1[1+dPdlc>m]dsmx

4

C, 31 30 28 27

k;f(n){putch(k++)<n&&f(n);}

Poiché putch non è standard, ecco la versione pienamente conforme:

k;f(n){putchar(k++)<n&&f(n);}

Deve essere chiamato dal principale:

main(){f(255);}

EDIT: migliorato sfruttando il valore di ritorno di putchar
EDIT 2: ridotto di un altro personaggio attraverso la ricorsione


1
putch è una funzione non standard. Inoltre, posso chiedere perché questa risposta è stata sottoposta a downgrade?
Stuntddude,

@Stuntddude Aggiungerò una versione alternativa che usa putchar, e non ho idea del perché questo sia sottoposto a downgrade. Dopotutto, è uno di quelli più corti.
Takra,

4

Perl, 17 byte

say chr for 0..$_

1
Troppe parentesi. print chr for 0..$ARGV[0]
arte

Hai ragione! È da un po 'che non uso Perl
Demnogonis,

1
È possibile utilizzare shiftinvece di $ARGV[0]salvare 2 byte.
nyuszika7h,

Se ti è permesso stampare i caratteri su linee diverse, puoi usare say. Inoltre, il conteggio dei personaggi è più breve se lo fai come una linea con -n. echo "90" | perl -nE'say chr for 0..$_'conterebbe come 18personaggi. 17per say chr for 0..$_più 1per il n.
hmatt1,

Hai ragione. Ma saynon funzionerà con tutte le versioni di perl.
Demnogonis,

3

CJam, 3

,:c

Ho ipotizzato che l'argomento fosse l'elemento in cima allo stack.

Esempio di utilizzo:

256,:c

ri,:c


3

awk - 27

{while(i<$0)printf"%c",i++}

Per dare il parametro su stdin eseguirlo come segue:

awk '{while(i<$0)printf"%c",i++}' <<<96

Solo per divertimento: la "versione positiva positiva" che inizia con un definitivo yes:

yes|head -96|awk '{printf"%c",NR-1}'

NR-1è necessario per la stampa (char)0per NR==1. :-(

E perché non abbiamo un nocomando? Questo è un po 'cattivo!


1
alias no='yes no'
nyuszika7h

... ma poi dovrei contare anche i caratteri di quella definizione di alias ... :-(

3

J - 5 byte

{.&a.

{.is Head, a.is Alphabet (un elenco di tutti i caratteri) e &li lega, generando un verbo monadico chiamato come:

{.&a. 100 NB. first 100 characters

Nota : sembra che questo non funzioni in modo interattivo: Jconsole e jQt sembrano impostare una traduzione, producendo caratteri box invece di alcuni caratteri di controllo. In uno script o dalla riga di comando, funziona però:

  ijconsole <<< '127 {. a.' | hd

Si noti che l'alfabeto non è esattamente ASCII.
FUZxxl,

Fino a {.&a. 127, non è vero?
jpjacobs,

No perché J ha caratteri di disegno a scatola anziché alcuni caratteri di controllo.
FUZxxl,

In realtà, scrivere questo in un file e controllarlo con un visualizzatore esadecimale mi dice che J produce i valori corretti (0x00 0x01, ...). è solo l'interprete / IDE J che interpreta questi valori come caratteri boxdrawing anziché caratteri di controllo. Fa esattamente lo stesso di tutte le altre lingue che usano charo equivalenti.
jpjacobs,

È strano perché l'ho testato sulla mia scatola UNIX e ha effettivamente emesso caratteri Unicode per alcuni dei punti di codice.
FUZxxl


3

Brainfuck, 44 byte

,
[
  <[>++++++++++<-]
  -[>-<-----]
  >+++>,
]
<[>.+<-]

Si aspetta una stringa decimale senza una nuova riga finale.

Provalo online.

Leggere numeri interi nell'intervallo [0, max_cell_size]in brainfuck non è difficile. Ti incoraggio a inventare un metodo pulito da solo. Lo considero un esercizio di livello per principianti. (L'operazione inversa di stampa del valore numerico di una cella è più coinvolta e potrebbe essere considerata un'attività di livello intermedio.)

Ecco una versione a 58 byte in grado di gestire 256implementazioni a 8 bit:

,
[
  <[<+> >++++++++++<-]
  -[>-<-----]
  >+++>,
]
<[>]
-<<[>.]
>[>+.<-]


Why haven't I thought of this??? This is ingenious!!!
FinW

Can I borrow this to use on future answers?
FinW

1
@FinW I'm guessing you don't know about this meta post.
Mitch Schwartz

2

Golfscript - 5

Thanks to @Dennis

~,''+

1
~,""+ is shorter and correctly processes input from STDIN.
Dennis

@Dennis That doesn't produce any output for me...
Beta Decay

1
Are you using the online interpeter? To correctly simulate input from STDIN, you have to use, e.g., ;"65", since the input from STDIN will always be a string.
Dennis

1
@Dennis Oh thanks that works now!
Beta Decay

2

Lua - 43 41 Bytes

for i=1,arg[1]do print(string.char(i))end

You can shorten this by a byte a=""for i=1,arg[1]do print(a.char(i))end
Digital Veer

You can shorten this by 2 bytes for i=1,arg[1]do print(("").char(i))end
manatwork

2

Befunge 98, 22

&:00pv>0gk,@
0::-1<^j`

Kind of sad that this is so long.

&:00p        ; gets numerical input, stores a copy at cell (0,0)               ;
     v       ; IP goes down                                                    ;

     <       ; IP goes left, so I execute 1-::0`j^                             ;
 ::-1        ; (1-::) subtract one from our number and duplicate it twice      ;
0       `    ; (0`) compare the number with 0, push 1 if greater else 0        ;
     <^j     ; if the result was 0, go up, otherwise continue going left       ;

      >0gk,  ; get the value at cell (0,0), print that many numbers from stack ;
           @ ; terminate program                                               ;

2

Python 3.4 - 36 bytes / 43 bytes

print(*map(chr,range(int(input()))))
print(*map(chr,range(int(input()))),sep='')

255 input()

How this works is:

  1. Get upper limit of range
  2. Generate a range of the table.
  3. Map the range to chr function ( takes int, returns ascii ).
  4. Consume the map via splat argument expansion ( number -> character -> print! )

The second one just removes the space separating each character in exchange for 7 bytes.


You could very much make this into a lambda, as the question states this, and in Python 2, map returns a list, so you could just do f=lambda i:map(chr,range(i))
Justin

That's true, and my initial solution was similar but I didn't want to use a lambda so that I could immediately print output. I wish map kept the trend of returning a list instead of an iterator, even if it is more pythonic that way.
Full Metal

2

Pascal 87

program _;var c:char;n:byte;begin n:=0;readln(n);for c:=chr(0)to chr(n)do write(c);end.

Pascal 73

program _;var c,n:byte;begin readln(n);for c:=0to n do write(chr(c));end.

Builds and runs fine from http://www.onlinecompiler.net/pascal


1
FreePascal (and if I remember correctly, Turbo Pascal too) only needs 60 of those characters: var c,n:byte;begin read(n);for c:=0to n do write(chr(c))end. pastebin.com/aFLVTuvh
manatwork

Quite possibly, I've only used Delphi. But someone edited that out of the title.
Mark K Cowan

2

x86 ASM (Linux) (many many bytes unless you compile it)

Written as a function, assumes parameter is passed in AX (I forget the number for the read syscall) Also doesn't preserve [SP] or BX.

test ax,ax
jz @Done
mov [sp],ax
@Loop:
mov ax,4
mov bx,1
mov cx,sp
mov dx,1
int 0x80
sub [sp],1  ; Can I do this?  Or do I need to load/sub/store separately?
jnz @Loop
@Done:
ret

2
(I should have put a F00F exploit in there, it's not like anyone will run it anyway)
Mark K Cowan

7
I was going to run this. I'm not going to run this now.
Aearnus


2

Ruby, 23

f=->n{puts *?\0..n.chr}

Explanation

  • Input is taken as the argument to a lambda. It expects an Integer.
  • The "destructuring operator" (*) invokes #to_ary on the Range to print every character on its own line.

2

Julia: 20 characters (REPL)

This is close to the question's example: just generates the characters and let the REPL to do whatever it wants with them.

f(n)=map(char,[0:n])

Julia: 33 characters

Prints each character in a separate line.

print(map(char,[0:int(ARGS[1])]))

2

M (MUMPS) - 21

R n F i=1:1:n W $C(i)

In expanded form: READ n FOR i=1:1:n WRITE $CHAR(i)


2

T-SQL: 68 63

As a print loop

DECLARE @i INT=64,@ INT=0A:PRINT CHAR(@)SET @+=1IF @<=@i GOTO A

T-SQL: 95 86

As a query

DECLARE @ INT=64SELECT TOP(@+1)CHAR(ROW_NUMBER()OVER(ORDER BY 0/0)-1)FROM sys.messages

Edit: Made changes and fixes pointed out by Muqo. Thanks. Fixes and golfing suggested by @t-clausen.dk


For the loop, you can save 5 or so characters converting the WHILE to a GOTO with label. For the query, maybe specify msdb.sys.objects to guarantee enough objects. Also, it doesn't output CHAR(0). However, as consolation you can ORDER BY @.
Muqo

Second answer is invalid. You can rewrite it this way and golf 9 characters: DECLARE @ INT=64SELECT TOP(@+1)CHAR(ROW_NUMBER()OVER(ORDER BY 0/0)-1)FROM sys.messages
t-clausen.dk

@t-clausen.dk not sure how I let that one through. Thanks for that.
MickyT

2

BrainFuck - 140 112 Bytes

,>,>,>-[>+<-----]>---[<+>-]<[<<<->->->-]<[>+<-]<[>>++++++++++<<-]<[>>>>++++++++++[<++++++++++>-]<<<<-]>>>[>.+<-]

Try It Here!

Saved 28 bytes by changing [<<<->>>->+<]>[<<<->>>->+<]>[<<<->>>-] to [<<<->->->-].

What it does

,>,>,>                                                              Takes three inputs
                                                                    in three separate cells

-[>+<-----]>---[<+>-]<[<<<->->->-]<                                 Takes 48 off of each to
                                                                    convert them to decimal

[>+<-]<[>>++++++++++<<-]<[>>>>++++++++++[<++++++++++>-]<<<<-]>>>    Combines them into a
                                                                    three digit number by
                                                                    multiplying the first
                                                                    by 100, the second by
                                                                    10 and then adding all
                                                                    three

[>.+<-]                                                             Repeatedly prints the
                                                                    value of the adjacent
                                                                    cell and then adds one
                                                                    to it until it reaches
                                                                    the input value.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.