Feliz aniversário, Raffaele Cecco!

33

Raffaele Cecco é um programador que produziu alguns dos melhores videogames para o computador ZX Spectrum no final dos anos 80. Entre outros, ele desenvolveu o altamente aclamado Cybernoid e Exolon .

Raffaele completará 50 anos em 10 de maio de 2017 . Esse desafio é uma pequena homenagem a ele, pelas horas felizes que muitos de nós passamos jogando nesses jogos fantásticos e pela motivação que eles trouxeram.

O desafio

O objetivo é produzir uma marca de seleção retangular inspirada na tela do menu principal do Cybernoid , mas na arte ASCII.

Especificamente, a sequência "Happy birthday Raffaele Cecco "(observe o espaço final) será mostrada girando ao longo das bordas de um retângulo 12 × 5, com um tempo de pausa constante entre os instantâneos.

Por exemplo, supondo que o texto seja exibido no sentido horário e girado no sentido anti-horário (veja as opções abaixo), aqui estão três instantâneos consecutivos da marca de seleção retangular:

Happy birthd
           a
o          y
c           
ceC eleaffaR

então

appy birthda
H          y

o          R
cceC eleaffa

então

ppy birthday
a           
H          R
           a
occeC eleaff

e assim por diante.

Regras

Nenhuma entrada será aceita. A saída será através de STDOUT ou equivalente, ou em uma janela gráfica.

A saída deve realmente representar o texto girando; isto é, cada novo instantâneo deve substituir o anterior para dar a impressão de movimento. Isso pode ser feito de qualquer maneira, por exemplo, escrevendo o número apropriado de novas linhas para limpar efetivamente a tela. É aceitável se isso for válido apenas para um determinado tamanho de tela; basta especificá-lo na resposta.

As seguintes opções são aceitas:

  • O texto pode ser exibido no sentido horário ou anti-horário e pode ser girado no sentido horário ou anti-horário (os exemplos de instantâneos acima pressupõem exibição no sentido horário e rotação no sentido anti-horário).
  • A rotação deve continuar ciclicamente em um loop infinito (até que o programa seja interrompido) e pode iniciar em qualquer fase.
  • O tempo de pausa entre os instantâneos deve ser aproximadamente constante, mas pode ser escolhido livremente entre 0,1 e 1 s. Uma pausa inicial antes de exibir o primeiro instantâneo é aceitável.
  • As letras podem ser maiúsculas, minúsculas ou mistas (como no exemplo acima).
  • O espaço em branco à esquerda ou à direita é permitido.

Programas ou funções são permitidos, em qualquer linguagem de programação . As brechas padrão são proibidas.

Se possível, forneça um arquivo gif mostrando a saída ou um link para testar o programa.

O menor código em bytes vence.

Luis Mendo
fonte
4
E se for impossível substituir? Podemos usar 99 balões vermelhos ... novas linhas?
Titus
@Titus Só se que efetivamente limpa a tela e dá a impressão de texto em movimento (gif favor!)
Luis Mendo
"Isso pode ser feito por qualquer meio, por exemplo, escrevendo o número apropriado de novas linhas para limpar efetivamente a tela". - isso não depende do tamanho do console? É aceitável imprimir uma nova linha se (junto com o próximo retângulo) significa que a próxima iteração substitui a anterior (no meu pequeno console)?
Jonathan Allan
1
@ Jonathan Ok, basta fornecer um gif com o console para ver o efeito
Luis Mendo

Respostas:

8

Geléia , 74  65 bytes

“ÆÇÐÑ÷øœ‘Ṭœṗ⁸ṙ©-¤4421œ?U0¦;"⁷,⁶ẋ⁵¤¤ṁ9¤ȮœS.®ß
“9ɲcḟ#%⁴1t(ŀȷUCOw⁾»Ç

Versão do Windows em execução em um console cp-65001 de 6 linhas de altura.
Há uma pausa de meio segundo (mais avaliação) entre as iterações:

gif de saída

Quão?

“9ɲcḟ#%⁴1t(ŀȷUCOw⁾»Ç - Main link: no arguments
“9ɲcḟ#%⁴1t(ŀȷUCOw⁾»  - compression of [d( Happy)+d( birthday)+d( Raff)+s(aele)+d( Ce)+d(cc)+s(o)] - d=dictionaryLookup, s=stringEncode.
                     -              = " Happy birthday Raffaele Cecco"
                   Ç - call last link (1) as a monad

“ÆÇÐÑ÷øœ‘Ṭœṗ⁸ṙ©-¤4421œ?U0¦;"⁷,⁶ẋ⁵¤¤ṁ9¤ȮœS.®ß - Link 1, rotate, print, recurse: string s
                ¤                            - nilad followed by link(s) as a nilad:
            ⁸                                -   link's left argument (initially s)
               -                             -   literal -1
             ṙ                               -   rotate left -1 (e.g. "blah" -> "hbla")
              ©                              -   copy to register and yield
“ÆÇÐÑ÷øœ‘                                    - literal: [13,14,15,16,28,29,30]
         Ṭ                                   - untruth: [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1]
          œṗ                                 - partition right at truthy indexes of left
                                             -   chops up the rotated string into 8
                                             -   e.g. [" Happy birth",'d','a','y'," Raffaele Ce",'c','c','o'])
             4421œ?                          - get the 4421st permutation of those items
                                             -   e.g. [" Happy birth",'o','d','c','a','c','y'," Raffaele Ce"]
                         ¦                   - apply to indexes:
                        0                    -   0 (right most)
                       U                     -   upend  (e.g. " Raffaele Ce" -> "eC eleaffaR ")
                                     ¤       - nilad followed by link(s) as a nilad:
                                  ¤          -   nilad followed by link(s) as a nilad:
                                 ¤           -     nilad followed by link(s) as a nilad:
                              ⁶              -       literal space
                                ⁵            -       literal 10
                               ẋ             -       repeat: "          "
                            ⁷                -     literal new line
                             ,               -     pair: ['\n',"          "]
                                     9       -   literal 9
                                    ṁ        -   mould like: ['\n',"          ",'\n',"          ",'\n',"          ",'\n',"          ",'\n']
                           "                 - zip with:
                          ;                  -   concatenation
                                             -     e.g. [" Happy birth\n","o          ","d\n","c          ","a\n","c          ","y\n","eC eleaffaR           ","\n"])
                                      Ȯ      - print and yield
                                         .   - literal 0.5
                                       œS    - after sleeping right seconds yield left
                                          ®  - recall value from register (s rotated by 1)
                                           ß - call this link (1) with the same arity (as a monad)
Jonathan Allan
fonte
16

HTML + ES6, 200 bytes

<pre id=o><script>setInterval(_=>o.innerHTML=(f=k=>k--?f(k)+(k<11?s[k]:k>47?s[74-k]:k%12?++k%12?' ':s[10+k/12]+`
`:s[30-k/12]):'')(60,s=s.slice(1)+s[0]),99,s="Happy birthday Raffaele Cecco ")</script>

Arnauld
fonte
Parece ótimo!
Luis Mendo
@LuisMendo Isso traz de volta memórias, embora eu me lembre do Cybernoid II melhor que o primeiro. Tenho certeza que já vi esse efeito em alguns cracktros também. ;-)
Arnauld
Sim, eu também preferiu a segunda :-)
Luis Mendo
11

ZX Spectrum BASIC, 187 bytes

Irritado que Philip tenha me vencido por alguns minutos :-) Números como \{15}são códigos de controle não imprimíveis - compile com zmakebas se você quiser mexer. Observe que o retângulo completo não é impresso imediatamente, mas se encaixa após os primeiros quadros.

1 let a$=" Happy birthday Raffaele Cecco":dim b$(code"\{15}"):dim c$(pi*pi)
3 let b$=a$(sgn pi)+b$:let a$=a$(val"2" to)+a$(sgn pi):print "\{0x16}\{0}\{0}";a$(to code"\{12}")'b$(sgn pi);c$;a$(val"13")'b$(val"2");c$;a$(code"\{14}")'b$(pi);c$;a$(len b$)'b$(val"4" to):go to pi

Experimente aqui (versão emulada em JS on-line, pressione Enter para iniciar) ... http://jsspeccy.zxdemo.org/cecco/

Você também pode salvar quatro bytes limpando a tela entre os quadros em vez de fazer uma PRINT AT, mas é muito instável para valer a pena ...

1 let a$=" Happy birthday Raffaele Cecco":dim b$(code"\{15}"):dim c$(pi*pi)
3 let b$=a$(sgn pi)+b$:let a$=a$(val"2" to)+a$(sgn pi):cls:print a$(to code"\{12}")'b$(sgn pi);c$;a$(val"13")'b$(val"2");c$;a$(code"\{14}")'b$(pi);c$;a$(len b$)'b$(val"4" to):go to pi
gasman
fonte
1
Ah, mas você ganha por um monte de bytes :-)
Philip Kendall
2
Bem-vindo ao PPCG!
Martin Ender
1
Bem-vindo ao jogo. ZX é sempre bom de ver. Boa resposta. +1.
ElPedro
10

V, 75 71 70 bytes

4 bytes salvos graças a @DJMcMayhem

iHappy birthd
±± a
o±° y
c±± 
ceC eleaffaR6ògÓÉ {dêjP2Ljjx1Lp5LxkpGd

Aqui está um link do TIO, mas observe que isso não funcionará no TIO porque o programa faz um loop infinito. Experimente online!

Como esse código contém não imprimíveis, aqui está um hexdump.

00000000: 6948 6170 7079 2062 6972 7468 640a b1b1  iHappy birthd...
00000010: 2061 0a6f b1b0 2079 0a63 b1b1 200a 6365   a.o.. y.c.. .ce
00000020: 4320 656c 6561 6666 6152 1b36 f267 d3c9  C eleaffaR.6.g..
00000030: 207b 64ea 6a50 324c 166a 6a78 314c 7035   {d.jP2L.jjx1Lp5
00000040: 4c78 6b70 4764                           LxkpGd

O tempo de sono é de 500 milissegundos.

giffy

Kritixi Lithos
fonte
Você pode dar um link TIO?
Rɪᴋᴇʀ
Algumas dicas (nem todas testadas): H|-> {. <C-v>êx-> , e 5L->}
DJMcMayhem
Além disso, seus comandos repchar estão todos usando 9, quando você poderia usar 10 ou 11. Por exemplo: alterar as médias de três linhas para ±± a, o° yec±±<space>
DJMcMayhem
@DJMcMayhem Tudo funciona, mas 5L=> }.
Kritixi Lithos
@Riker feito, mas nota que o link TIO não pode mostrar a animação
Kritixi Lithos
9

ZX Spectrum BASIC, 274 bytes

Bem, alguém tinha que fazer isso. Os pedantes podem querer desqualificar isso por ser muito lento e não ter uma pausa entre as animações, mas estou reivindicando um caso especial aqui :-)

10 LET m$=" Happy birthday Raffaele Cecco": LET o=0: LET l=LEN m$: LET f=4: LET t=12: LET a=t+f: LET b=27
20 FOR j=SGN PI TO l: LET i=j+o: IF i>l THEN LET i=i-l
40 LET x=(i-SGN PI AND i<=t)+(11 AND i>t AND i<=a)+(b-i AND i>a AND i<=b)
50 LET y=(i-t AND i>t AND i<=a)+(f AND i>a AND i<=b)+(b+f-i AND i>b): PRINT AT y,x;m$(j): NEXT j
80 LET o=o+SGN PI: IF o>=l THEN LET o=o-l
90 GO TO t

Também não é muito golfista. 274 bytes é o número de bytes salvos pelo Spectrum em fita ao salvar este programa.

Philip Kendall
fonte
1
Você foi para todos os problemas de utilizar SGN PIpara 1(poupa 5 bytes) mas você esqueceu NOT PIde 0e VALpara as outras constantes ...
Neil
1
NOT PIEu apenas errei. Deliberadamente não fez VALcomo era lento o suficiente, e VALé terrivelmente lento.
Philip Kendall
1
O ZX Basic sempre recebe um voto positivo de mim. Não há pedantismo aqui. Lembro-me dos bons velhos tempos ... Ótima resposta.
ElPedro 10/10
8

SVG (HTML5), 267 bytes

<svg width=200 height=90><defs><path id=p d=M40,20h120v50h-120v-50h120v50h-120v-50></defs><text font-size="19" font-family="monospace"><textPath xlink:href=#p>Happy birthday Raffaele Cecco<animate attributeName=startOffset from=340 to=0 dur=5s repeatCount=indefinite>

Bem, é retangular, e é uma marquise, e é texto ASCII ...

Neil
fonte
1
... e roda smooooth :-)
Luis Mendo
7

PHP, 184 bytes

for($r=" ";++$i;sleep(print chunk_split(str_pad($r,96,"
",0),12)),$r=$k="0")for(;$c="ABCDEFGHIJKWco{zyxwvutsrqpdXL@"[$k];)$r[ord($c)-64]="Happy Birthday Raffaele Cecco "[($i+$k++)%30];

imprime 39 novas linhas para limpar a tela; corra com -nr.
A pausa real é de 1 segundo; mas eu acelerei o gif.

Feliz Aniversário

destroçado

$p = "ABCDEFGHIJKWco{zyxwvutsrqpdXL@";  # (positions for characters)+64 to ASCII
$t = "Happy Birthday Raffaele Cecco ";  # string to rotate
for($r=" ";                     # init result to string
    ++$i;                       # infinite loop
    $r=$k="0")                      # 6. reset $r and $k
{
    for(;$c=$p[$k];)                # 1. loop through positions
        $r[ord($c)-64]=                 # set position in result
        $t[($i+$k++)%30];               # to character in string
    sleep(                          # 5. wait 1 second
        print                       # 4. print
            chunk_split(
            str_pad($r,96,"\n",0)   # 2. pad to 96 chars (prepend 36 newlines)
            ,12)                    # 3. insert newline every 12 characters
        );
}
Titus
fonte
6

Python 2, 230 184 bytes

import time
s='Happy birthday Raffaele Cecco '*2
i=0
while[time.sleep(1)]:print'\n'*30+'\n'.join([s[i:i+12]]+[s[i-n]+' '*10+s[i+11+n]for n in 1,2,3]+[s[(i+15)%30:][11::-1]]);i+=1;i%=30

Experimente em repl.it

insira a descrição da imagem aqui

ovs
fonte
5

Python 3 , 160 bytes

import time;s="Happy_birthday_Raffaele_Cecco_"
while[time.sleep(1)]:print(s[:12]+'\n%s%%11s'*3%(*s[:-4:-1],)%(*s[12:15],)+'\n'+s[-4:14:-1]+'\n'*30);s=s[1:]+s[0]

Experimente online! (Sem animação)

xnor
fonte
Eu meio que sabia que você entraria e me venceria com Python. Eu estava indo tão bem! Pelo menos o meu usa "bugs" que você não pode usar com o Python 3 :-). Boa resposta como sempre. +1
ElPedro 10/10
5

Python 2, 218 200 190 181 176 bytes

import time;f='Happy birthday Raffaele Cecco '
while[time.sleep(1)]:v=f[::-1];print'\n'*90,f[:12],''.join('\n'+a+' '*10+b for a,b in zip(v[:3],f[12:16])),'\n',v[3:15];f=f[1:]+f[0]

-18 bytes removendo a strformatação

-10 bytes, graças às sugestões @Uriel e @ElPedro

-9 bytes removendo a indexação negativa

-5 bytes armazenando invertido fcomo vewhile condições condições

repl.it

Wondercricket
fonte
1
Você pode cortar o espaço em branco entre while 1:e printe substitua o próximo ;com uma nova linha (real). Também f='H... Também f[:1]é verdade f[0].
Uriel
O OP afirma que o tempo pode estar entre 0,1 e 1 segundos; por que não time.sleep(1)levá-lo abaixo de 200?
ElPedro 9/05
3

Ruby + GNU Core Utils, 136 bytes

s='Happy birthday Raffaele Cecco '
loop{puts`clear`+s[0,12],(0..2).map{|i|s[~i]+' '*10+s[12+i]},s[15,12].reverse
s=s[1,29]+s[0];sleep 1}
Value Ink
fonte
3

Python 2, 182 179 173 160 bytes

i="Happy birthday Raffaele Cecco "
while[s for s in i*18**4]:print'\n'*99,'\n'.join([i[:12]]+[i[-z]+' '*10+i[11+z]for z in 1,2,3]+[i[15:-3][::-1]]);i=i[1:]+i[0]

Experimente em repl.it

Como o TIO não funciona, minha primeira tentativa de usar repl.it

Editar uso de um loop "perda de tempo" para contar até 1000000 fornece um atraso consistente entre 0,1 e 1s na minha máquina e no repl.it e salva a importaçãotime . Acho que se você o executou em um computador antigo 286 com 64 MB de RAM, pode demorar mais de um segundo, mas tenho certeza de que isso não acontecerá. Se isso acontecer, basta reduzir os 1000000 e salvar alguns bytes :-)

Edite 2 -6 para lembrar que as compreensões da lista no Python 2 vazam o último valor des para que eu possa usá-lo mais tarde e também para lembrar que praticamente qualquer coisa que não seja 0 e "" é verdadeira. Erros ou recursos? Não se importe. Ele me salvou 6 bytes :-)

Editar 3 Outros 13 reverenciando a rotação e usando uma compreensão de lista para as linhas do meio dentro da junção e alterando 3000000para40**4 . Obrigado a @FelixDombek pela última. Tive que perder o meu truque de compreensão da lista.

ElPedro
fonte
1
Você poderia usar notação científica ou uma expressão de poder para o grande número?
Felix Dombek
1
Expressão de poder sim, notação científica não (porque se torna um objeto flutuante, que você não pode multiplicar por seqüências de caracteres).
L3viathan
3
Obrigatório em 999999vez de 1000000por um byte: V
Value Ink
Graças @ValueInk mas usando a lista de fuga compreensão "bug" Eu realmente tive que aumentar para 3000000 e ainda salvou 3 bytes :-)
ElPedro
Infelizmente não. @ L3viathan está certo nisso.
ElPedro
2

Código da máquina ZX81 Z80, 158 130 bytes

OK, então ele possui muitos bytes até ser montado, mas depois cai para 130 bytes. Não tem certeza se isso quebra alguma regra? É o meu primeiro post e apenas como convidado.

O programa usa 'força bruta' para exibir a mensagem em vez do uso inteligente da função, como pode ser visto pelo modo como possui blocos de código separados para a linha superior, a direita direita, a linha inferior e a esquerda. A animação é obtida girando o conteúdo da mensagem e exibindo-a após um pequeno atraso, que deve ser exatamente de 0,2 segundos, enquanto aguarda 10 quadros em uma taxa de 50 (de qualquer maneira para o Zeddys do Reino Unido).

Eu tenho que dar crédito à kmurta pelo conceito de girar a mensagem para obter a animação - que economizou 28 bytes !!!

main    
  ld hl,happyBirthday           ;load the address of the message
  ld de,(D_FILE)                ;load the base of screen memory
  inc de                        ;increase it by one to bypass the $76
  ld bc,12                  ;ready for 12 loops
  ldir                      ;transfer HL to DE 12 times and increase both accordingly
  ex de,hl                  ;put HL into DE (HL was the message position)
  ld b,4                        ;prepare to loop 4 times
  dec hl                        ;decrease HL (screen location) by 1
rightVertical
  push de                       ;save the character position
  ld de,13                  ;load 13 (for the next line)
  add hl,de                 ;add to HL  
  pop de                        ;get the message position back
  ld a,(de)                 ;load the character into A
  ld (hl),a                 ;save it to HL
  inc de                        ;increase the character position
  djnz rightVertical            ;repeat until B = 0
  dec hl                        ;decrease HL (screen location) by 1 to step back from the $76 char
  ld b,11                       ;prepare for 11 loops
lastLine
  ld a,(de)                 ;load the current character into A
  ld (hl),a                 ;save to the screen
  dec hl                        ;decrease the screen position (as we are going backwards)
  inc de                        ;increase character position
  djnz lastLine             ;repeat until B = 0
  ld b,3                        ;get ready for the left vertical
  inc hl                        ;increase the screen position by 1 as we have gone 1 too far to the left and wrapped to the line above
leftVertical
  push de                       ;save the character position
  ld de,13                  ;load 13 (for the next line)
  sbc hl,de                 ;subtract it to move up a line in memory
  pop de                        ;get the character pos back
  ld a,(de)                 ;load the character
  ld (hl),a                 ;save it to the screen
  inc de                        ;next character
  djnz leftVertical         ;repeat until B = 0 
delayCode
  ld   hl,FRAMES                ;fetch timer                 
  ld   a,(hl)                 ;load into A                        
  sub  10                       ;wait 10 full frames (0.2 of a second)
delayLoop        
  cp  (hl)                  ;compare HL to 0
  jr   nz,delayLoop         ;if not 0 then repeat until it is   
shuffleMessage
  ld a, (happyBirthday)     ;load the first character of the message
  push af                       ;save the first character of the message
  ld hl, happyBirthday      ;load the address of the message
  inc hl                        ;increase by one to get the second char
  ld de, happyBirthday      ;load the start of the message
  ld bc, 29                 ;number of times to loop
  ldir                      ;load HL (char 2) into DE (char 1) and repeat
  pop af                        ;get char 1 back    
  ld (de),a                 ;out it at the end of the string
  jr main                       ;repeat
happyBirthday
    DEFB    _H,_A,_P,_P,_Y,__,_B,_I,_R,_T,_H,_D,_A,_Y,__,_R,_A,_F,_F,_A,_E,_L,_E,__,_C,_E,_C,_C,_O,__

Desculpe, não posso postar um link para ele em execução, pois é um programa compilado no formato .P para o EightyOne (ou outros emuladores) ou para um Zeddy real, se você tiver um ZXPand ou semelhante para carregá-lo.

O arquivo .P pode ser baixado em http://www.sinclairzxworld.com/viewtopic.php?f=11&t=2376&p=24988#p24988

Lardo Boffin
fonte
Boa resposta! Estava faltando um no código da máquina Z80 :-) E bem-vindo ao site!
Luis Mendo
Você poderia fornecer um gif do programa em execução?
Luis Mendo
Desculpe - não tenho software de criação de gif!
Lardo Boffin