Sua própria instrução "para"


38

Sua própria instrução "para"

Supondo que você tenha a seguinte entrada: a, b, c, d

A entrada pode estar em uma linha usando qualquer formato "a / b / c / d" ou "a, b, c, d" etc.

Você também pode ter 4 entradas.

Você deve codificar o seguinte comportamento (pseudo-código aqui):

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

Aqui estão alguns casos de testes:

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

Mais um :

input : 20,>,10,1
output :
20
21
22
23
24
25
26
27
...
infinite loop / program crashes
  • aé um número inteiro , o valor inicial de i.

  • bé uma string ou um char , não pode ser outra coisa, o comparador usado na condição final do forloop.

    bpode e deve ser uma das seguintes strings:

    - ">"
    - "<"
    
  • cé um número inteiro , o número usado na condição final do for loop.

  • dé um número inteiro que é adicionado a i em cada loop.

Este é o código-golfe, a resposta mais curta ganha!


1
Os números podem ser retornados de uma função como uma lista / sequência, em vez de serem impressos em stdout?
SMLS

@smls Não, desculpe, a saída deve ser como os exemplos!
Sygmei

1
Ele diz que meu código deve seguir o pseudo-código e existe um print "\n", mas estou usando o alerta do javascript para cada linha. Isso seria aceitável ou eu teria que usar o console.log em vez de prolongar minha resposta?

2
Você pode usar a função de alerta como uma maneira de enviar, mas não pode usar vários alertas. Algo como alert("23\n24\n25");iria funcionar enquanto alert("23"); alert("24"); alert(25);não o faria
Sygmei

Respostas:


25

JavaScript (ES6),  44  43 56 bytes

Economizou 1 byte graças ao ETHproductions
Edit: corrigido para atender aos requisitos de saída

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

Teste


Bom uso do escopo!
ETHproductions

Eu acho que você pode reorganizar o evalpara salvar um byte:(a,b,c,d)=>{for(;eval(a+b+c);a+=d)alert(a)}
ETHproductions

@ETHproductions Ah, sim. Agradável!
precisa

5
Isso é um 44 com um tutu!
aross

Isso não segue a especificação em que a saída é linha por linha com U + 000A após cada linha.
Joey

17

Javascript (ES6), 47 42 48 bytes

Queria fazer a versão for, mas alguém foi mais rápido, então aqui está a versão recursiva.

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

Você precisa adicionar f=antes e chamá-lo como f(b,c,d)(a).

Muito obrigado a Arnauld pelo golfe incrível.

alertalterado para console.logpor causa da especificação de saída


@ Arnauld Obrigado, é um golfe bem legal. Eu apenas perguntei a ele, então vamos ver se ele aceita.

Fico feliz em vê-lo aceito. ;)
Arnauld 26/01

Isso não segue a especificação em que a saída é linha por linha com U + 000A após cada linha.
Joey

@ Joey Isso é apenas pseudo-código, mas vou perguntar à OP sobre isso.

@ Masterzagh: Havia uma pergunta sobre formatos de saída alternativos já que foi negada.
Joey


13

Gelatina , 12 bytes

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

Experimente online!

O Jelly tem várias maneiras de fazer iterações, criar intervalos, etc. Mas, espelhar o comportamento do C ++ exatamente é bastante difícil, devido a casos especiais como o incremento sendo 0, o loop terminando antes de iniciar (devido à desigualdade ao contrário) ) e o incremento indo na direção errada (o que significa que a condição de saída do loop não pode ser atendida naturalmente). Como tal, essa solução é basicamente uma tradução direta do C ++, embora isso o torne um nível mais baixo do que normalmente é um programa Jelly. Felizmente, o C ++ tem um comportamento indefinido no estouro de número inteiro assinado (a pergunta usa int), o que significa que um programa pode fazer qualquer coisa nesse caso e, portanto, não há necessidade de tentar imitar o comportamento do estouro.

Explicação

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

Falhando no programa é a maneira mais concisa de desativar a saída implícita do Jelly (caso contrário, ele produziria o valor final do contador); ele gera várias mensagens de erro no stderr, mas normalmente consideramos isso permitido.

Aliás, o contador do loop é inicializado com o valor atual antes do loop iniciar. Como o loop aparece no início do programa, essa será a primeira entrada.


Você pode mudar tpara não ter travamento. A desenfileiramento resulta em uma lista vazia para a qual a impressão implícita de Jelly não produz nada.
Jonathan Allan

@ JonathanAllan: Não, o que realmente faz é criar um intervalo de 2 a um valor determinado, o que é definitivamente visível em uma impressão implícita.

Ah, eu devo ter testado essa teoria com um loop terminando em território negativo; de fato, um intervalo é criado implicitamente.
Jonathan Allan

Uhm, são 12 caracteres, mas não são 12 bytes, certo?
Cruncher

@Cruncher: Jelly usa sua própria codificação, na qual cada caractere usado pelo idioma é representado por um único byte (ele usa apenas 256 caracteres diferentes). O motivo pelo qual ele não usa algo mais conhecido como a página de código 437 é facilitar a digitação (quero dizer, não é fácil digitar, mas é mais fácil do que uma linguagem como o gs2). Um hexdump deste programa teria 12 bytes.



9

Java, 58 bytes

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

14
Existe um motivo para criar i? Você poderia pular a parte de inicialização e apenas usar a? Além disso, o uso do valor ASCII de '>' (62) salva um byte.
Riley

6
Após o comentário de Riley, você pode fazerb>61
Kritixi Lithos

Eu não acredito que isso compila.
ChiefTwoPencils

@ChiefTwoPencils É uma função. Você precisa escrever um programa de teste para compilá-lo.
precisa saber é o seguinte

@ wizzwizz4, obviamente. Mas isso ainda não funciona. Experimente. Além disso, meu entendimento é de todos os bytes necessários para executá-lo.
ChiefTwoPencils

7

05AB1E , 22 20 bytes

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

Experimente online!

Explicação

[                       # 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
Qualquer formato de entrada é aceita assim a segunda versão é :) bem
Sygmei

7

SmileBASIC, 53 bytes

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

Explicação:

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

Isso usa o fato de que X<Yé o mesmo que-X>-Y


Eu vou confiar em você para este, eu não tenho um 3DS para teste :)
Sygmei

Eu tenho Petit Computer, idéia tão legal! Vou tentar algo parecido com isso em algum momento ...
python-b5

Você pode usar uma READinstrução, economizando 1 byte.
Ckjbgames

@ckjbgames how?
12Me21

@ 12Me21 Verifique os manuais do SmileBASIC. Deve estar na lista de instruções do SmileBASIC.
Ckjbgames

6

Empilhados , 34 bytes

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

Experimente online! (Teste incluído.) Essa é uma função que espera que a pilha se pareça com:

a b c d

Por exemplo:

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

Explicação

@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

Opa, isso C++não é C. Fiquei um pouco confuso com a pergunta.

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

Isso é C ou C ++?
betseg

10
Qual implementação de C ++? (Estou curioso para saber como obter algo parecido using namespace stdde graça).
H Walters

Não iprecisa começar a, não 0? Você pode simplesmente usar ae pular icompletamente e usar o valor ASCII de '>'. for(;b==62?a>c:a<c;a+=d)
Riley

Não funciona paraf(1,'<'3,1);
Roman Gräf

Ack ... sim, requer a matemática dos dois lados; for(b-=61;b*a>b*c;a+=d)trabalha para um único byte; mas o mesmo acontece for(;b-62?a<c:a>c;a+=d).
H Walters



4

Pip , 14 bytes

W Va.b.ca:d+Pa

Leva quatro argumentos de linha de comando. Suporta números de ponto flutuante e negativo e operadores de comparação < > = <= >= !=. Experimente online!

                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éia , 8 bytes

ḢṄ+⁹;µV¿

Esse é um link diádico que leva a, b, c como argumento à esquerda ed como seu argumento à direita. A saída pode ser infinita e vai para STDOUT.

Experimente online!

Como 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.

Os argumentos da linha de comando usam a sintaxe Python e não podem distinguir entre um caractere e uma string singleton. Se você deseja usar CLAs, é necessário inserir um Fpara achatar a matriz.
Dennis

2
Agora, quero excluir metade do meu comentário, pois está obsoleto, mantendo a outra metade. Acho que vou repetir a metade relevante e excluir o restante: "Ah, ah, você definiu como uma função para poder desconsiderar a saída implícita sob as regras do PPCG. Eu deveria ter pensado nisso."

4

Python 2 , 45 bytes

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

Experimente online!

Uma implementação muito literal da especificação. Pega o modelo de código, substitui as entradas por formatação de string e o executa.


4

TeX simples, 88 bytes

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

O comando \forfornece a função solicitada. Salve isso for.texe, em seguida, execute-o e insira os valores das variáveis ​​na linha de comandos: pdftex '\input for \for 1 < 5 1 \bye'Os valores das variáveis ​​devem ser separados por espaços.


4

Python 3, 61 bytes

Um forro:

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

Bem vindo ao site! Bom uso do novo recurso de interpolação de cadeia literal. Eu acho que você pode salvar um byte substituindo \tpor um espaço.
0

Obrigado. Ainda tem o mesmo tamanho depois de remover o \ n \ t após o terceiro e ()
G-Ox7cd


3

Bash (+ Ferramentas Unix), 29 bytes

Golfe

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

Teste

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

1
Ha. Eu estava prestes a postar exatamente a mesma coisa! +1
Digital Trauma


3

Lisp comum, 82 80 79 73 64 bytes

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

Teste

(f 1 < 10 1)

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

-9 bytes graças a PrzemysławP.


Talvez você possa salvar 9 bytes, definindo uma 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 Obrigado novamente!
Coredump

3

PHP, 69 65 bytes

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

Execute com '-r'; fornecer argumentos de linha de comando como entrada.

Por apenas um byte a mais 4 bytes, posso usar todos os operadores:

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

Sim, avaliação do mal. Você sabia que isso pode retornar algo?


A desestruturação abreviada [,$i,$b,$c,$d]=$argv;economizaria mais 4 bytes;
mas o PHP 7.1 pós-desafio.


Arrumado ! Eu não tinha certeza quando criar o desafio se eu deveria incluir todos os operadores comuns, então me lembrei que eles não são todos iguais (~ = for = na Lua, por exemplo!)
Sygmei

Uau, eval é mau.
precisa saber é

Parece-me que você pode usar o PHP 7.1 para torná-lo mais curto. Se não for assim o uso de listsalva 4 bytes mais 4 bytes com sintaxe curta
Jörg Hülsermann

O @PHP 7.1 pós-desafio; mas obrigado por list().
Titus

2

Perl 6 , 44 bytes

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

Como 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.

Se não há problema em retornar uma sequência (potencialmente infinita) de números como um valor do tipo Seq, em vez de imprimir os números no stdout, a .say forpeça pode ser removida, reduzindo-a para 35 bytes.


2

Clojure, 66 63 bytes

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

-3 bytes fatorando o loop. Estou "abusando" do parâmetro init para atuar como acumulador em execução.

Solução recursiva (com TCO). Veja os comentários no código pré-escrito. Tentei uma solução recursiva não-TCO e ela acabou sendo de 67 bytes.

Eu adoraria ver essa batida em Clojure! Eu acho que este é o menor que posso 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) 

Oh, eu não percebi essa resposta. #(when(({">">"<"<}%2)% %3)(println %)(recur(+ % %4)%2 %3 %4))seria 61 bytes, combinando o seu whencom o meu ({">">"<"<}%2).
precisa saber é o seguinte

2

Groovy, 51 bytes

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

Este é um fechamento sem nome. Experimente Online!

Cuidado - Se você quiser testar isso groovy console, mate todo o processo quando a entrada causar um loop infinito. Percebi isso depois que consumiu ~ 5 GB de RAM.


2

QBIC , 51 40 bytes

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

E três minutos após a postagem, percebi que poderia simplificar a lógica do 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

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

Se não fosse o comportamento do segundo parâmetro, poderia ser feito em 53 bytes:

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

Isso simplesmente não faz nada se a etapa tiver o sinal errado. O teste extra é porque o forloop do lote permite que a variável do loop seja igual ao valor final.


2

Clojure, 66 bytes

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

Poderia ter 55 bytes <e >são funções no Clojure:

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

Eu gosto do uso do mapa aqui. Eu nunca teria pensado que isso teria batido no meu caminho. Também interessante que ambas as nossas contagens iniciais fossem as mesmas, apesar de abordagens ligeiramente diferentes.
Carcigenicate

Permitindo b ser uma função daria uma vantagem injusta para alguns idiomas :)
Sygmei

É verdade, mas eu acho que a maioria das línguas que eu conheço não se beneficiariam muito de permitir que <, em vez de "<", exceto Clojure.
precisa saber é o seguinte

@Sygmei True. Seria muito doce embora. Não posso culpar você por fazer essa ligação.
precisa saber é o seguinte

OP disse que os caracteres são bons em vez de cadeias de caracteres para os operadores de comparação. Isso deve economizar alguns bytes.
precisa saber é o seguinte

2

TI-Basic, 41 34 bytes

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

1
Da maneira que uma calculadora de TI funciona, muitos símbolos são armazenados como um único byte. Prompt , Str2, Str3, While , expr(, Disp , ->, E Endsão todos os símbolos de um byte. Eu conto 29 bytes.
Pavel

@ Pavel Obrigado pelo seu interesse! Embora seja verdade que o TI-Basic é tokenizado, nem todos os tokens têm um byte. Por exemplo, Str2, Str3, e expr(são todas as fichas de dois bytes. Para ver uma lista de tokens de um byte, consulte tibasicdev.wikidot.com/one-byte-tokens
Timtech 27/17/17
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.