Votre propre instruction "pour"


38

Votre propre "pour" instruction

En supposant que vous ayez les entrées suivantes: a, b, c, d

La saisie peut se faire sur une ligne, quel que soit le format "a / b / c / d" ou "a, b, c, d", etc.

Vous pouvez également avoir 4 entrées.

Vous devez coder le comportement suivant (pseudo-code ici):

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

Voici quelques cas de tests:

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

Un de plus :

input : 20,>,10,1
output :
20
21
22
23
24
25
26
27
...
infinite loop / program crashes
  • aest un entier , la valeur initiale de i.

  • best une chaîne ou un omble chevalier , il ne peut pas être autre chose, le comparateur utilisé dans l'état de fin de la forboucle.

    bpeut et doit être l'une des chaînes suivantes:

    - ">"
    - "<"
    
  • cest un entier , le nombre utilisé dans la condition de fin de la for boucle.

  • dest un entier ajouté à i à chaque boucle.

C'est du code-golf, la réponse la plus courte gagne!


1
Les numéros peuvent-ils être renvoyés d'une fonction sous forme de liste / séquence plutôt que d'être imprimés sur la sortie standard?
smls

@smls Non désolé, la sortie doit être comme les exemples!
Sygmei

1
Il dit que mon code doit suivre le pseudo-code et il y en a un print "\n", mais j'utilise l'alerte javascript pour chaque ligne. Cela serait-il acceptable ou devrais-je utiliser console.log à la place, ce qui allongerait ma réponse?

2
Vous pouvez utiliser la fonction d'alerte comme moyen d'exporter, mais vous ne pouvez pas utiliser plusieurs alertes. Quelque chose comme ça alert("23\n24\n25");marcherait alors que ça ne marcherait alert("23"); alert("24"); alert(25);pas
Sygmei

Réponses:


25

JavaScript (ES6),  44  43 56 octets

Enregistré 1 octet grâce à ETHproductions
Edit: corrigé pour se conformer aux exigences de sortie

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

Tester


Belle utilisation de la portée!
ETHproductions

Je pense que vous pouvez réorganiser le evalpour économiser un octet:(a,b,c,d)=>{for(;eval(a+b+c);a+=d)alert(a)}
ETHproductions

@ETHproductions Ah, oui. Joli!
Arnauld

5
C'est un 44 avec un tutu!
aross

Cela ne suit pas la spécification où la sortie est ligne à ligne avec U + 000A après chaque ligne.
Joey

17

Javascript (ES6), 47 42 48 octets

Voulait faire la version pour, mais quelqu'un était plus rapide, alors voici la version récursive.

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

Vous devez ajouter f=avant et appeler comme ça f(b,c,d)(a).

Un grand merci à Arnauld pour son superbe golf.

alertchangé en console.lograison de la spécification de sortie


@Arnauld Merci, c'est un golf plutôt cool. Je viens de lui demander, alors voyons s'il l'accepte.

Content de le voir accepté. ;)
Arnauld

Cela ne suit pas la spécification où la sortie est ligne à ligne avec U + 000A après chaque ligne.
Joey

@ Joey C'est juste du pseudo-code, mais je vais demander à OP à ce sujet.

@ Masterzagh: Il y avait déjà une question sur les formats de sortie alternatifs qui avait déjà été refusée.
Joey


13

Gelée , 12 octets

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

Essayez-le en ligne!

Jelly a beaucoup de façons de résumer, créer des plages, etc. Cependant, refléter exactement le comportement de C ++ est assez difficile, en raison de cas spéciaux tels que l'incrément étant 0, la boucle se terminant avant de commencer (en raison de l'inégalité inversée ), et l’incrément allant dans la mauvaise direction (ce qui signifie que la condition de sortie de la boucle ne peut pas être remplie naturellement). En tant que telle, cette solution est fondamentalement une traduction directe du C ++, même si cela la rend plutôt de bas niveau qu'un programme Jelly. Heureusement, C ++ a un comportement indéfini en cas de dépassement d'entier signé (la question utilise int), ce qui signifie qu'un programme peut tout faire dans ce cas. Il n'est donc pas nécessaire d'essayer de reproduire le comportement de dépassement de capacité.

Explication

Ṅ+⁶µ⁴;⁵¹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)

Arrêter le programme est le moyen le plus rapide de désactiver la sortie implicite de Jelly (sinon, la valeur finale du compteur serait sortie); cela génère un tas de messages d'erreur sur stderr, mais nous considérons normalement que cela est autorisé.

Incidemment, le compteur de boucle est initialisé avec la valeur actuelle avant le début de la boucle. Lorsque la boucle apparaît au début du programme, ce sera la première entrée.


Vous pouvez changer tpour ne pas avoir l' accident. La sortie de file d'attente produit une liste vide pour laquelle l'impression implicite de Jelly ne donne rien.
Jonathan Allan

@ JonathanAllan: En réalité, il s'agit de créer une plage allant de 2 à la valeur donnée, qui est clairement visible sur une impression implicite.

Ah, j'ai dû tester cette théorie avec une boucle se terminant en territoire négatif; en effet, une plage est créée implicitement.
Jonathan Allan

Euh, c'est 12 caractères, mais ce n'est pas 12 octets non?
Cruncher

@Cruncher: Jelly utilise son propre codage dans lequel chaque caractère utilisé par le langage est représenté par un seul octet (il utilise uniquement 256 caractères différents). La raison pour laquelle il n'utilise pas quelque chose de plus connu, comme la page de code 437, est pour faciliter la frappe (je veux dire, ce n'est pas si facile à taper, mais c'est plus facile que ne le serait un langage comme gs2). Un hexdump de ce programme aurait une longueur de 12 octets.



9

Java, 58 octets

(a,b,c,d)->{for(;b>61?a>c:a<c;a+=d)System.out.println(a);}

14
Y a-t-il une raison pour créer i? Pourriez-vous ignorer la partie d'initialisation et simplement l'utiliser a? De plus, l'utilisation de la valeur ASCII de '>' (62) enregistre un octet.
Riley

6
Après le commentaire de Riley, vous pouvez le faireb>61
Kritixi Lithos le

Je ne crois pas que cela compile.
ChiefTwoPencils le

@ChiefTwoPencils C'est une fonction. Vous devez écrire un programme de test autour de lui pour le compiler.
wizzwizz4

@ wizzwizz4, évidemment. Mais ça ne marche toujours pas. Donner un coup de feu. De plus, ma compréhension est que tous les octets nécessaires pour l'exécuter comptent.
ChiefTwoPencils

7

05AB1E , 22 à 20 octets

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

Essayez-le en ligne!

Explication

[                       # 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

1
N'importe quel format d'entrée est accepté, donc la deuxième version est correcte :)
Sygmei

7

SmileBASIC, 53 octets

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

Explication:

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

Ceci utilise le fait qui X<Yest le même que-X>-Y


Je vais te faire confiance pour celui-ci, je n'ai pas de 3DS à tester :)
Sygmei

J'ai un petit ordinateur, idée géniale! Je vais essayer quelque chose comme ça un jour ...
python-b5

Vous pouvez utiliser une READdéclaration en sauvegardant 1 octet.
ckjbgames

@ckjbgames comment?
12Me21

@ 12Me21 Consultez les manuels SmileBASIC. Il devrait figurer dans la liste des instructions pour SmileBASIC.
ckjbgames

6

Empilés , 34 octets

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

Essayez-le en ligne! (Test inclus.) C'est une fonction qui s'attend à ce que la pile ressemble à ceci:

a b c d

Par exemple:

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

Explication

@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

4

C ++, 80

Oups, ce n'est C++pas C. Était un peu confus par la question.

void f(int a,char b,int c,int d){for(;b==62?a>c:a<c;a+=d)cout<<a<<endl;}

Est-ce C ou C ++?
mardi

10
Quelle implémentation de C ++? (Je suis curieux de savoir comment vous obtenez quelque chose de semblable using namespace stdgratuitement).
H Walters

Ne doit pas icommencer à a, non 0? Vous pouvez simplement utiliser aet ignorer icomplètement et utiliser la valeur ASCII de '>'. for(;b==62?a>c:a<c;a+=d)
Riley

Ne fonctionne pas pourf(1,'<'3,1);
Roman Gräf

Ack ... ouais, il faut savoir calculer les deux côtés; for(b-=61;b*a>b*c;a+=d)fonctionne pour un seul octet; mais le fait aussi for(;b-62?a<c:a>c;a+=d).
H Walters



4

Pip , 14 octets

W Va.b.ca:d+Pa

Prend quatre arguments en ligne de commande. Prend en charge les nombres négatifs et à virgule flottante et les opérateurs de comparaison < > = <= >= !=. Essayez-le en ligne!

                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

4

Gelée , 8 octets

ḢṄ+⁹;µV¿

This is a dyadic link that takes a,b,c as its left argument and d as its right one. Output may be infinite and goes to STDOUT.

Try it online!

How it works

ḢṄ+⁹;µ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.

Command-line arguments use Python syntax and cannot distinguish between a character and a singleton string. If you want to use CLAs, you have to insert an F to flatten the array.
Dennis

2
Now I want to delete half my comment as it's obsolete, whilst keeping the other half. I guess I'll just repeat the relevant half and delete the rest: "Oh, bleh, you defined it as a function so you could disregard the implicit output under PPCG rules. I should have thought of that."

4

Python 2, 45 bytes

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

Try it online!

A very literal implementation of the spec. Takes the code template, substitutes in the inputs via string formatting, and executes it.


4

Plain TeX, 88 bytes

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

The command \for provides the requested function. Save this as for.tex and then run it and enter the variable values at the command line: pdftex '\input for \for 1 < 5 1 \bye' The variable values must be separated by spaces.


4

Python 3, 61 bytes

One liner:

e=input;exec(f'i={e()}\nwhile i{e()}{e()}:print(i);i+={e()}')

Welcome to the site! Nice use of the new literal string interpolation feature. I think you might be able to save a byte by replacing \t with a space.
0 '

Thank you.still the same size after removing the \n\t after third e()
G-Ox7cd


3

Bash (+Unix Tools), 29 bytes

Golfed

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

Test

./forloop 1 '<' 10 1
1
2
3
4
5
6
7
8
9

1
Ha. I was just about to post the exact same thing! +1
Digital Trauma

3

Ruby, 43 41 bytes

->a,*i,d{a=d+p(a)while eval"%s"*3%[a,*i]}

If b can be taken in as a Ruby symbol instead of a string, you get 38 bytes:

->a,b,c,d{a=d+p(a)while[a,c].reduce b}

Try either solution online!


3

Common Lisp, 82 80 79 73 64 bytes

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

Test

(f 1 < 10 1)

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

-9 bytes thanks to PrzemysławP.


Perhaps you can save 9 bytes, by defining a macro. (defmacro f(a b c d)<insert backqoute here>(do((i,a(+ i,d)))((not(,b i,c)))(print i))) Usage: (f 1 < 10 1)

@PrzemysławP Thanks again !
coredump

3

PHP, 69 65 bytes

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

Run with '-r'; provide command line arguments as input.

For just one byte more 4 more bytes, I can take every operator:

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

Yeah, evil eval. Did you know that it can return something?


Shorthand destructuring [,$i,$b,$c,$d]=$argv; would save 4 more bytes;
but PHP 7.1 postdates the challenge.


Neat ! I wasn't sure when creating the challenge if I should include every common operators, then I remembered that they aren't all the same (~= for != in Lua for example)
Sygmei

Woah, eval IS evil.
cyberbit

It seems to me that you can use PHP 7.1 to make it shorter. If it is not so the use of list saves 4 Bytes plus 4 Bytes with short syntax
Jörg Hülsermann

@PHP 7.1 postdates the challenge; but thanks for list().
Titus

2

Perl 6, 44 bytes

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

How it works

{                                          }  # 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.

If it's okay to return a (potentially infinite) sequence of numbers as a value of type Seq, instead of printing the numbers to stdout, the .say for part could be removed, bringing it down to 35 bytes.


2

Clojure, 66 63 bytes

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

-3 bytes by factoring out the loop. I'm "abusing" the init parameter to act as the running accumulator.

Recursive solution (with TCO). See comments in pregolfed code. I tried a non-TCO recursive solution, and it ended up being 67 bytes.

I'd love to see this beat in Clojure! I think this is the smallest I can get it.

(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) 

Oh I didn't notice this answer. #(when(({">">"<"<}%2)% %3)(println %)(recur(+ % %4)%2 %3 %4)) would be 61 bytes, combining your when with my ({">">"<"<}%2).
NikoNyrh

2

Groovy, 51 bytes

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

This is an unnamed closure. Try it Online!

Caution - If you want to test this with groovy console, make sure you kill the entire process when the input causes an infinite loop. I noticed this after it consumed ~5 gigs of RAM.


2

QBIC, 51 40 bytes

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

And three minutes after posting I realised I could simplify the terminator logic...

:;::      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

2

Batch, 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

If it wasn't for the second parameter behaviour, it could be done in 53 bytes:

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

This simply does nothing if the step has the wrong sign. The extra test is because Batch's for loop allows the loop variable to equal the end value.


2

Clojure, 66 bytes

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

This could have been 55 bytes as< and > are functions in Clojure:

(def f #(loop[i %](if(%2 i %3)(do(println i)(recur(+ i %4))))))
(f 1 < 10 1)

I like the use of the map here. I would have never thought that that would have beaten my way. Also interesting that both of our initial counts were the same, despite slightly different approaches.
Carcigenicate

Allowing b to be a function would give an unfair advantage to some languages :)
Sygmei

True, but I think most languages I know of wouldn't benefit much from allowing < instead of "<", except Clojure.
NikoNyrh

@Sygmei True. It would be freakin sweet though. Can't blame you making that call.
Carcigenicate

OP said characters are fine instead of strings for the comparison operators btw. That should save a couple bytes.
Carcigenicate

2

TI-Basic, 41 34 bytes

Prompt A,Str2,Str3,D
While expr("A"+Str2+Str3
Disp A
A+D->A
End

1
The way that a TI calculator works, many symbols are stored as a single byte. Prompt , Str2, Str3, While , expr(, Disp , ->, and End are all single-byte symbols. I count 29 bytes.
Pavel

@Pavel Thanks for your interest! Although it's true that TI-Basic is tokenized, not all tokens are one byte. For example, Str2, Str3, and expr( are all two-byte tokens. To see a list of one-byte tokens, check out tibasicdev.wikidot.com/one-byte-tokens
Timtech
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.