Tu propia instrucción "para"

38

Tu propia instrucción "para"

Suponiendo que tiene la siguiente entrada: a, b, c, d

La entrada puede estar en una línea usando cualquier formato "a / b / c / d" o "a, b, c, d", etc.

También puede tener 4 entradas.

Debe codificar el siguiente comportamiento (pseudocódigo aquí):

var i = <a>
while (i <b> <c>)
    print i
    i = i + <d>
    print "\n"

Aquí hay algunos casos de prueba:

input : 1,<,10,1
output :
1
2
3
4
5
6
7
8
9

Uno mas :

input : 20,>,10,1
output :
20
21
22
23
24
25
26
27
...
infinite loop / program crashes
  • aes un entero , el valor inicial de i.

  • bes una cadena o un carácter , no puede ser otra cosa, el comparador utilizado en la condición final del forbucle.

    bpuede y debe ser una de las siguientes cadenas:

    - ">"
    - "<"
    
  • ces un número entero , el número utilizado en la condición final del for bucle.

  • des un entero que se agrega a i en cada bucle.

Este es el código de golf, ¡la respuesta más corta gana!

Sygmei
fuente
1
¿Se pueden devolver los números de una función como una lista / secuencia, en lugar de imprimirse en stdout?
sonríe el
@smls ¡No, lo siento, la salida debe ser como los ejemplos!
Sygmei
1
Dice que mi código debe seguir el pseudocódigo y hay un print "\n", pero estoy usando la alerta de JavaScript para cada línea. ¿Sería eso aceptable o tendría que usar console.log en lugar de hacer que mi respuesta sea más larga?
2
Puede usar la función de alerta como una forma de salida, pero no puede usar varias alertas. Algo así alert("23\n24\n25");funcionaría mientras alert("23"); alert("24"); alert(25);que no lo haría
Sygmei

Respuestas:

25

JavaScript (ES6),  44  43 56 bytes

Guardado 1 byte gracias a ETHproductions
Edit: corregido para cumplir con los requisitos de salida

(a,b,c,d)=>{for(s='';eval(a+b+c);a+=d)s+=a+`
`;alert(s)}

Prueba

Arnauld
fuente
Buen uso de alcance!
ETHproductions
Creo que puede reorganizar el evalpara guardar un byte:(a,b,c,d)=>{for(;eval(a+b+c);a+=d)alert(a)}
ETHproductions
@ETHproductions Ah, sí. ¡Buena esa!
Arnauld
55
Eso es un 44 con un tutú!
Aross
Esto no sigue la especificación donde la salida es línea por línea con U + 000A después de cada línea.
Joey
17

Javascript (ES6), 47 42 48 Bytes

Quería hacer la versión for pero alguien era más rápido, así que aquí está la versión recursiva.

(b,c,d)=>F=a=>eval(a+b+c)&&console.log(a)|F(a+d)

Necesita agregar f=antes y llamarlo como f(b,c,d)(a).

Muchas gracias a Arnauld por el increíble golf.

alertcambiado a console.logdebido a la especificación de salida


fuente
@Arnauld Gracias, ese es un golf muy bueno. Solo le pregunté, así que veamos si lo acepta.
Me alegra verlo aceptado. ;)
Arnauld
Esto no sigue la especificación donde la salida es línea por línea con U + 000A después de cada línea.
Joey
@Joey Eso es solo un seudocódigo, pero le preguntaré a OP sobre esto.
@Masterzagh: Ya había una pregunta sobre formatos de salida alternativos que fue denegada.
Joey
15

Puro bash, 35

Supongo que está bien solo para conectar los parámetros en el bucle estándar:

for((i=$1;i$2$3;i+=$4));{ echo $i;}

Pruébalo en línea .

Trauma digital
fuente
Jaja, bash lo hace realmente fácil
Sygmei
13

Jalea , 12 bytes

Ṅ+⁶µ⁴;⁵¹vµ¿t

Pruébalo en línea!

Jelly tiene muchas maneras de hacer iteraciones, crear rangos, etc. Sin embargo, reflejar exactamente el comportamiento de C ++ es bastante difícil, debido a casos especiales como que el incremento es 0, el ciclo termina antes de que comience (debido a que la desigualdad está al revés) ), y el incremento va en la dirección incorrecta (lo que significa que la condición de salida del bucle no se puede cumplir de forma natural). Como tal, esta solución es básicamente una traducción directa de C ++, aunque eso lo hace bastante más bajo que un programa Jelly normalmente. Afortunadamente, C ++ tiene un comportamiento indefinido en el desbordamiento de enteros con signo (la pregunta usaint ), lo que significa que un programa puede hacer cualquier cosa en ese caso y, por lo tanto, no hay necesidad de intentar imitar el comportamiento de desbordamiento.

Explicación

Ṅ+⁶µ⁴;⁵¹vµ¿t
   µ     µ¿   While loop; while ((⁴;⁵¹v) counter) do (counter = (Ṅ+⁶)counter).
    ⁴;⁵       Second input (b) appended to third input (c), e.g. "<10"
        v     Evaluate, e.g. if the counter is 5, "<10" of the counter is true
       ¹      No-op, resolves a parser ambiguity
Ṅ             Output the counter, plus a newline
 +⁶           Add the fourth input (d)
           t  Crashes the program (because the counter is not a list)

Bloquear el programa es la mejor manera de desactivar la salida implícita de Jelly (de lo contrario, generaría el valor final del contador); genera un montón de mensajes de error en stderr, pero normalmente consideramos que está permitido.

Por cierto, el contador de bucle se inicializa con el valor actual antes de que comience el bucle. Como el bucle aparece al comienzo del programa, esa será la primera entrada.


fuente
Podrías cambiar ta no tener ningún bloqueo. El resultado final es una lista vacía para la cual la impresión implícita de Jelly no produce nada.
Jonathan Allan
@JonathanAllan: No lo hace, lo que realmente hace es crear un rango de 2 al valor dado, que definitivamente es visible en una impresión implícita.
Ah, debo haber probado esa teoría con un bucle que termina en territorio negativo; de hecho, un rango se crea implícitamente.
Jonathan Allan
Uhm, esto son 12 caracteres, pero no son 12 bytes ¿verdad?
Cruncher
@Cruncher: Jelly usa su propia codificación en la que cada carácter utilizado por el idioma está representado por un solo byte (solo usa 256 caracteres diferentes). La razón por la que no usa algo mejor conocido como la página de códigos 437 es para que sea más fácil de escribir (quiero decir, no es tan fácil de escribir, pero es más fácil de lo que sería un lenguaje como gs2). Un hexdump de este programa tendría 12 bytes de longitud.
10

R, 63 bytes

function(a,b,c,d)while(do.call(b,list(a,c))){cat(a,"\n");a=a+d}
Sven Hohenstein
fuente
9

Java, 58 bytes

(a,b,c,d)->{for(;b>61?a>c:a<c;a+=d)System.out.println(a);}
Roman Gräf
fuente
14
¿Hay alguna razón para crear i? ¿Podría omitir la parte de inicialización y simplemente usar a? Además, el uso del valor ASCII de '>' (62) guarda un byte.
Riley
66
Siguiendo el comentario de Riley, puedes hacerlob>61
Kritixi Lithos
No creo que esto compile.
ChiefTwoPencils
@ChiefTwoPencils Es una función. Tienes que escribir un programa de prueba alrededor para compilarlo.
wizzwizz4
@ wizzwizz4, obviamente. Pero eso todavía no funciona. Dale un tiro. Además, entiendo que todos los bytes necesarios para ejecutarlo cuentan.
ChiefTwoPencils
7

05AB1E , 22 20 bytes

[D²`'>Q"‹›"è.V_#D,³+

Pruébalo en línea!

Explicación

[                       # start loop
 D                      # copy top of stack (current value of a)
  ²`                    # push b,c to stack
    '>Q                 # compare b to ">" for equality
       "‹›"             # push this string
           è            # index into the string with this result of the equality check
            .V          # execute this command comparing a with c
              _#        # if the condition is false, exit loop (and program)
                D,      # print a copy of the top of the stack (current value of a)
                  ³+    # increment top of stack (a) by d
Emigna
fuente
1
Se acepta cualquier formato de entrada, por lo que la segunda versión está bien :)
Sygmei
7

SmileBASIC, 53 bytes

INPUT A,B$,C,D
S=ASC(B$)-61WHILE S*A>S*C?A
A=A+D
WEND

Explicación:

INPUT A,B$,C,D
IF B$=="<" THEN S=-1 ELSE S=1 'get comparison direction
I=A
WHILE S*I>S*C 'loop while I is less than/greater than the end
 PRINT I
 INC I,D
WEND

Esto usa el hecho de que X<Yes lo mismo que-X>-Y

12Me21
fuente
Confiaré en ti para este, no tengo un 3DS para probar :)
Sygmei
Tengo Petit Computer, ¡es una idea genial! Intentaré algo como esto alguna vez ...
python-b5
Podría usar una READdeclaración, ahorrando 1 byte.
ckjbgames
@ckjbgames ¿cómo?
12Me21
@ 12Me21 Consulte los manuales de SmileBASIC. Debe estar en la lista de instrucciones para SmileBASIC.
ckjbgames
6

Apilado , 34 bytes

@d@c@b[show d+][:c b tofunc!]while

Pruébalo en línea! (Pruebas incluidas.) Esta es una función que espera que la pila se vea así:

a b c d

Por ejemplo:

1 '<' 10 2
@d@c@b[show d+][:c b tofunc!]while

Explicación

@d@c@b[show d+][:c b tofunc!]while
@d@c@b                               assign variables
               [............]while   while:
                :c                   duplicate "i" and push c
                   b tofunc!         convert b to a function and execute it
      [.......]                      do:
       show                          output "i" without popping
            d+                       and add the step to it
Conor O'Brien
fuente
4

C ++, 80

Vaya, esto C++no es C. Estaba un poco confundido por la pregunta.

void f(int a,char b,int c,int d){for(;b==62?a>c:a<c;a+=d)cout<<a<<endl;}
Roman Gräf
fuente
¿Es esto C o C ++?
betseg el
10
¿Qué implementación de C ++? (Tengo curiosidad por saber cómo obtienes algo similar using namespace stdde forma gratuita).
H Walters
No itiene que empezar por a, 0¿ no ? Puede usar ay omitir por icompleto y usar el valor ASCII de '>'. for(;b==62?a>c:a<c;a+=d)
Riley
No funciona paraf(1,'<'3,1);
Roman Gräf
Ack ... sí, requiere las matemáticas en ambos lados; for(b-=61;b*a>b*c;a+=d)funciona para un solo byte; Pero también lo hace for(;b-62?a<c:a>c;a+=d).
H Walters
4

C, 52 51 bytes

-1 byte gracias a H Walters

f(a,b,c,d){for(;b&2?a>c:a<c;a+=d)printf("%d\n",a);}

Pruébalo en línea!

simon
fuente
1
Perdón por el error en el pseudocódigo, incrementé después de cada impresión :)
Sygmei
1
Use en b&2lugar de b^60para otro byte.
H Walters
4

Python 3, 52 bytes

def f(a,b,c,d):
 while[a>c,a<c][b<'>']:print(a);a+=d

repl.it

Jonathan Allan
fuente
¡Uso inteligente de las listas!
Sygmei
4

Pip , 14 bytes

W Va.b.ca:d+Pa

Toma cuatro argumentos de línea de comandos. Admite números negativos y de coma flotante y operadores de comparación < > = <= >= !=. Pruébalo en línea!

                a,b,c,d are cmdline args
W               While loop with the following condition:
  Va.b.c          Concatenate a,b,c and eval
            Pa  Print a with newline (expression also returns value of a)
        a:d+    Add d to that and assign back to a
DLosc
fuente
4

Jalea , 8 bytes

ḢṄ+⁹;µV¿

Este es un enlace diádico que toma a, b, c como argumento izquierdo yd como argumento derecho. La salida puede ser infinita y va a STDOUT.

Pruébalo en línea!

Cómo funciona

ḢṄ+⁹;µV¿  Dyadic link.
          Left argument:  a,b,c (integer, character, integer)
          Right argument: d     (integer)

       ¿  While...
      V     the eval atom applied to a,b,c returns 1:
     µ       Combine the links to the left into a chain and apply it to a,b,c.
Ḣ              Head; pop and yield a from a,b,c.
 Ṅ             Print a, followed by a linefeed.
  +⁹           Add a and the right argument (d) of the dyadic link.
    ;          Concatenate the result and the popped argument of the chain,
               yielding a+d,b,c.
Dennis
fuente
Los argumentos de la línea de comandos usan la sintaxis de Python y no pueden distinguir entre un carácter y una cadena singleton. Si desea usar CLA, debe insertar un Fpara aplanar la matriz.
Dennis
2
Ahora quiero eliminar la mitad de mi comentario, ya que es obsoleto, manteniendo la otra mitad. Supongo que repetiré la mitad relevante y eliminaré el resto: "Oh, bleh, lo definiste como una función para que puedas ignorar el resultado implícito bajo las reglas PPCG. Debería haber pensado en eso".
4

Python 2 , 45 bytes

exec"i=%d\nwhile i%c%d:print i;i+=%d"%input()

Pruébalo en línea!

Una implementación muy literal de la especificación. Toma la plantilla de código, sustituye las entradas a través del formato de cadena y la ejecuta.

xnor
fuente
4

TeX simple, 88 bytes

\newcount\i\def\for#1 #2 #3 #4 {\i#1\loop\the\i\endgraf\advance\i#4\ifnum\i#2#3\repeat} 

El comando \forproporciona la función solicitada. Guarde esto como for.texy luego ejecútelo e ingrese los valores variables en la línea de comando: pdftex '\input for \for 1 < 5 1 \bye'Los valores variables deben estar separados por espacios.

musaritmia
fuente
4

Python 3, 61 bytes

Un trazador de líneas:

e=input;exec(f'i={e()}\nwhile i{e()}{e()}:print(i);i+={e()}')
G-Ox7cd
fuente
Bienvenido al sitio! Buen uso de la nueva función de interpolación de cadenas literales. Creo que puede guardar un byte reemplazándolo \tcon un espacio.
0
Gracias. Todavía del mismo tamaño después de eliminar el \ n \ t después de la tercera e ()
G-Ox7cd
3

Bash (+ Herramientas Unix), 29 bytes

Golfed

bc<<<"for(x=$1;x$2$3;x+=$4)x"

Prueba

./forloop 1 '<' 10 1
1
2
3
4
5
6
7
8
9
zepelín
fuente
1
Decir ah. ¡Estaba a punto de publicar exactamente lo mismo! +1
Trauma digital
3

Lisp común, 82 80 79 73 64 bytes

(defmacro f(a b c d)`(do((i,a(+ i,d)))((not(,b i,c)))(print i)))

Prueba

(f 1 < 10 1)

1 
2 
3 
4 
5 
6 
7 
8 
9 
NIL
CL-USER> 

-9 bytes gracias a PrzemysławP.

volcado de memoria
fuente
Quizás pueda guardar 9 bytes, definiendo una macro. (defmacro f(a b c d)<insert backqoute here>(do((i,a(+ i,d)))((not(,b i,c)))(print i)))Uso:(f 1 < 10 1)
@ PrzemysławP Gracias de nuevo!
coredump
3

PHP, 69 65 bytes

for(list(,$i,$b,$c,$d)=$argv);$b<"="?$i<$c:$i>$c;$i+=$d)echo"$i
";

Ejecutar con '-r'; proporcionar argumentos de línea de comando como entrada.

Por solo un byte más 4 bytes más, puedo tomar todos los operadores:

for(list(,$i,$b,$c,$d)=$argv;eval("return $i$b$c;");$i+=$d)echo"$i
";

Sí, malvado eval. ¿Sabías que puede devolver algo?


La desestructuración abreviada [,$i,$b,$c,$d]=$argv;ahorraría 4 bytes más;
pero PHP 7.1 es posterior al desafío.

Titus
fuente
Ordenado ! No estaba seguro al crear el desafío si debía incluir todos los operadores comunes, entonces recordé que no son todos iguales (~ = for! = En Lua, por ejemplo)
Sygmei
Woah, eval ES malvado.
cyberbit el
Me parece que puedes usar PHP 7.1 para acortarlo. Si no es así, el uso delist guardar 4 Bytes más 4 Bytes con sintaxis corta
Jörg Hülsermann
@PHP 7.1 es posterior al desafío; pero gracias por list().
Titus
2

Perl 6 , 44 bytes

{.say for $^a,*+$^d...^*cmp$^c!= $^b.ord-61}

Cómo funciona

{                                          }  # A lambda.
          $^a                                 # Argument a.
             ,*+$^d                           # Iteratively add d,
                   ...^                       # until (but not including the endpoint)
                       *cmp$^c                # the current value compared to c
                                              # (less=-1, same=0, more=1)
                              != $^b.ord-61.  # isn't the codepoint of the b minus 61.
 .say for                                     # Print each number followed by a newline.

Si está bien devolver una secuencia (potencialmente infinita) de números como un valor de tipo Seq, en lugar de imprimir los números en stdout, la .say forparte podría eliminarse, reduciéndola a 35 bytes.

smls
fuente
2

Clojure, 66 63 bytes

#(when((if(= %2"<")< >)% %3)(println %)(recur(+ % %4)%2 %3 %4))

-3 bytes factorizando el loop. Estoy "abusando" del parámetro init para actuar como el acumulador en ejecución.

Solución recursiva (con TCO). Ver comentarios en código pregolfed. Intenté una solución recursiva no TCO, y terminó siendo 67 bytes.

¡Me encantaría ver este ritmo en Clojure! Creo que esto es lo más pequeño que puedo conseguir.

(defn my-for [init-num com-str com-num inc-num]
  (let [op (if (= com-str "<") < >)] ; Figure out which operator to use
    (when (op init-num com-num) ; When the condition is true, print and recur
      (println init-num)
      (recur (+ init-num inc-num) com-str com-num inc-num))))
    ; Else, terminate (implicit) 
Carcigenicate
fuente
Oh, no me di cuenta de esta respuesta. #(when(({">">"<"<}%2)% %3)(println %)(recur(+ % %4)%2 %3 %4))sería de 61 bytes, combinando tu whencon mi ({">">"<"<}%2).
NikoNyrh
2

Groovy, 51 bytes

{a,b,c,d->while(Eval.me("$a$b$c")){println a;a+=d}}

Este es un cierre sin nombre. Pruébalo en línea!

Precaución : si desea probar esto groovy console, asegúrese de eliminar todo el proceso cuando la entrada provoque un bucle infinito. Me di cuenta de esto después de que consumió ~ 5 gigas de RAM.

Gurupad Mamadapur
fuente
2

QBIC , 51 40 bytes

:;::{?a┘a=a+c~A=@<`|~a>=b|_X]\~a<=b|_X

Y tres minutos después de publicar, me di cuenta de que podía simplificar la lógica del terminador ...

:;::      Consecutively read a, A$, b and c from the command line
{?a┘      Start an infinite loop; print a, add a newline to the source
a=a+c     increment a
~A=@<`|   If we are in LESS THAN mode
  ~a>=b   and IF we are no longer LESS
    |_X]  THEN QUIT, end if.
  \       ELSE (we're in GREATER THAN mode)
    ~a<=b IF we are no longer GREATER
    |_X   THEN QUIT
          The last IF and the loop are auto-closed
Steenbergh
fuente
2

Lote, 94 bytes

@set i=%1
@set o=gtr
@if "%~2"=="<" set o=lss
:g
@if %i% %o% %3 echo %i%&set/ai+=%4&goto g

Si no fuera por el comportamiento del segundo parámetro, podría hacerse en 53 bytes:

@for /l %%i in (%1,%4,%n%)do @if not %%i==%3 echo %%i

Esto simplemente no hace nada si el paso tiene el signo incorrecto. La prueba adicional se debe a que el forciclo de Batch permite que la variable del ciclo sea igual al valor final.

Neil
fuente
2

Clojure, 66 bytes

#(loop[i %](if(({">">"<"<}%2)i %3)(do(println i)(recur(+ i %4)))))

Esto podría haber sido de 55 bytes como <y >son funciones en Clojure:

(def f #(loop[i %](if(%2 i %3)(do(println i)(recur(+ i %4))))))
(f 1 < 10 1)
NikoNyrh
fuente
Me gusta el uso del mapa aquí. Nunca hubiera pensado que eso me hubiera golpeado. También es interesante que nuestros dos recuentos iniciales fueran iguales, a pesar de los enfoques ligeramente diferentes.
Carcigenicar el
Permitir que b sea una función daría una ventaja injusta a algunos idiomas :)
Sygmei
Es cierto, pero creo que la mayoría de los idiomas que conozco no se beneficiarían mucho de permitir en <lugar de "<", excepto Clojure.
NikoNyrh
@Sygmei True. Sin embargo, sería increíblemente dulce. No puedo culparte haciendo esa llamada.
Carcigenicate
OP dijo que los caracteres están bien en lugar de cadenas para los operadores de comparación por cierto. Eso debería ahorrar un par de bytes.
Carcigenicar el
2

TI-Basic, 41 34 bytes

Prompt A,Str2,Str3,D
While expr("A"+Str2+Str3
Disp A
A+D->A
End
Timtech
fuente
1
La forma en que funciona una calculadora TI, muchos símbolos se almacenan como un solo byte. Prompt , Str2, Str3, While , expr(, Disp , ->, Y Endson todos los símbolos de un byte. Cuento 29 bytes.
Pavel
@Pavel ¡Gracias por tu interés! Aunque es cierto que TI-Basic está tokenizado, no todos los tokens son de un byte. Por ejemplo, Str2, Str3, y expr(son todas las fichas de dos bytes. Para ver una lista de tokens de un byte, consulte tibasicdev.wikidot.com/one-byte-tokens
Timtech