Escreva um programa válido após a troca circular de caracteres

17

Potencialmente muito difícil, mas já vi coisas incríveis saindo deste site.

O objetivo é escrever um programa, em qualquer idioma, que faça o que você quiser. O problema é que o programa deve ser válido após qualquer mudança circular dos caracteres.

Um deslocamento de caractere circular é muito semelhante a um deslocamento circular . Alguns exemplos são minhas coisas claras.

Para o programa int main() { return 0; }

deslocar para a esquerda em 6 caracteres produz: in() { return 0; }int ma

deslocar para a esquerda em 1 caractere gera: nt main() { return 0; }i

deslocar para a direita em 10 caracteres produz: eturn 0; }int main() { r

No entanto, este programa obviamente não cumpre as regras.

Regras

  • Qualquer língua
  • O vencedor é decidido pela contagem de votos positivos
  • As soluções que fazem a mesma coisa, ou coisas completamente diferentes para cada rotação, receberão 100 votos virtuais positivos em sua pontuação.

ATUALIZAÇÃO Acho que isso já dura bastante tempo. O vencedor, com mais votos (votos virtuais incluídos), é Mark Byers. Bem feito!

Griffin
fonte
5
Existem algumas respostas potenciais muito chatas em idiomas nos quais um int literal é um programa válido. Eles recebem um virtual -100?
Peter Taylor
11
@ PeterTaylor Estou assumindo que respostas chatas receberão menos votos.
Griffin
"Potencialmente muito difícil" É sempre útil conhecer muitas linguagens estranhas antes de fazer esse tipo de afirmação de uma maneira geral. Difícil em c ou java, claro, mas em idiomas com comandos de 1 caractere e sintaxes simples? Não muito.
precisa
@dmckee daí o "Potencialmente" ...
Griffin
@ PeterTaylor também em muitas línguas, o programa vazio é um programa válido
jk.

Respostas:

31

Use o idioma certo para a tarefa. Nesse caso, é o Befunge .

Esse idioma naturalmente permite rotações porque:

  • Todos os comandos são um único caractere.
  • O controle envolve quando chega ao final do programa, iniciando novamente desde o início.

Este programa Befunge imprime exatamente a mesma saída ("Hello"), independentemente de quantas "trocas de caracteres circulares" você usar:

86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p645**2-00p645**2-00p

Ele roda em Befungee . Requer que o tabuleiro seja aumentado (não o padrão de 80 caracteres). Pode ser executado assim:

python befungee.py -w400 hello.bef

Ele funciona primeiro gerando e armazenando dinamicamente um programa que imprime "Hello" e substituindo o primeiro byte para redirecionar o controle para o programa recém-gravado. O programa é gravado duas vezes para que, se um byte não for gravado corretamente na primeira vez, ele será corrigido na segunda vez.

A idéia poderia ser estendida para produzir qualquer programa de complexidade arbitrária.

Mark Byers
fonte
Entrada muito agradável!
ChristopheD
22

Brainf * ck

Escolha a ferramenta certa para o trabalho - um ditado que nunca foi tão relevante quanto este trabalho aqui!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++.+.>++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.++++++++++++++.>++++++++++.+

O programa não deslocado que você vê aqui simplesmente imprime SHIFT(mais uma nova linha). Mudanças circulares abitrariamente produzirão várias outras saídas, embora sempre produza seis caracteres ASCII.

caixa de pão
fonte
Li a pergunta e pensei: Brainfuck, esse é o bilhete, mas você me venceu.
jmoreno
12

Commodore 64 BASIC

?é abreviação de PRINTe :é um separador de instrução, portanto:

?1:?2:?3:          // prints 1, 2, and 3
:?1:?2:?3          // prints 1, 2, and 3
3:?1:?2:?          // adds a program line 3 :PRINT1:PRINT2:PRINT
?3:?1:?2:          // prints 3, 1, and 2
:?3:?1:?2          // prints 3, 1, and 2
2:?3:?1:?          // adds a program line 2 :PRINT3:PRINT1:PRINT
?2:?3:?1:          // prints 2, 3, and 1
:?2:?3:?1          // prints 2, 3, and 1
1:?2:?3:?          // adds a program line 1 :PRINT2:PRINT3:PRINT

É claro que variações mais longas são possíveis:

?1:?2:?3:?4:?5:?6:?7:?8:?9:?10:?11:

etc ...

Danko Durbić
fonte
11

Golfscript

Este programa imprime alguns dígitos que sempre somam 2, independentemente de como o programa é alterado:

10 2 base
0 2 base1
 2 base10
2 base10 
 base10 2
base10 2 
ase10 2 b
se10 2 ba
e10 2 bas

A primeira linha é impressa 1010(10 em binário), a segunda linha é impressa 02e todas as outras linhas são impressas 2.

Atualizar:

O programa pode ser testado aqui . Observe que eu adicionei ns no final de cada linha apenas para formatar a saída; estes podem ser removidos e o programa ainda funciona.

Cristian Lupascu
fonte
10

Ruby, provavelmente uma das soluções mais curtas possíveis:

p

E outra um pouco mais longa e mais interessante:

;;p";p;";p
Jon
fonte
9

binário x86 de 16 bits

Construído manualmente com a ajuda dessas ( 1 2 ) tabelas, nasm e ndisasm. Isso sempre retornará sem uma falha ou loop infinito, porque nenhum bytes salta ou altera a pilha e é preenchido com NOPs para terminar com uma retinstrução de byte único em qualquer caso.

Na maioria dos casos, isso resultará em FOOuma substring. Se AXestiver quebrado, isso chamará um int 10 aleatório (isso mudou a velocidade de piscar do cursor em um dos meus testes), mas geralmente não resulta em uma falha.

Para experimentar, coloque o hexdump em um arquivo e use-o xxd -r foo.hex > foo.come execute em um ambiente DOS (usei o dosbox).

Aqui está um dump hexadecimal deste arquivo:

0000000: b846 0d90 90fe c490 9090 bb05 0090 9043  .F.............C
0000010: 43cd 1090 b84f 0d90 90fe c490 9090 bb05  C....O..........
0000020: 0090 9043 43cd 1090 b84f 0d90 90fe c490  ...CC....O......
0000030: 9090 bb05 0090 9043 43cd 1090 9090 c3    .......CC......

E algumas compensações desmontadas interessantes:

+0

00000000  B8420D            mov ax,0xd42
00000003  90                nop
00000004  90                nop
00000005  FEC4              inc ah
00000007  90                nop
00000008  90                nop
00000009  90                nop
0000000A  BB0500            mov bx,0x5
0000000D  90                nop
0000000E  90                nop
0000000F  43                inc bx
00000010  43                inc bx
00000011  CD10              int 0x10
00000013  90                nop
00000014  B84F0D            mov ax,0xd4f
00000017  90                nop
00000018  90                nop
00000019  FEC4              inc ah
0000001B  90                nop
0000001C  90                nop
0000001D  90                nop
0000001E  BB0500            mov bx,0x5
00000021  90                nop
00000022  90                nop
00000023  43                inc bx
00000024  43                inc bx
00000025  CD10              int 0x10
00000027  90                nop
00000028  B84F0D            mov ax,0xd4f
0000002B  90                nop
0000002C  90                nop
0000002D  FEC4              inc ah
0000002F  90                nop
00000030  90                nop 
00000031  90                nop
00000032  BB0500            mov bx,0x5
00000035  90                nop
00000036  90                nop
00000037  43                inc bx
00000038  43                inc bx
00000039  CD10              int 0x10
0000003B  90                nop
0000003C  90                nop
0000003D  90                nop
0000003E  C3                ret

(para os exemplos abaixo, o restante do binário ainda é válido)

+1

00000000  42                inc dx
00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

+2

00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

+6

00000000  C4909090          les dx,[bx+si-0x6f70]
00000004  BB0500            mov bx,0x5
00000007  90                nop
00000008  90                nop
00000009  43                inc bx
0000000A  43                inc bx
0000000B  CD10              int 0x10

+11

00000000  050090            add ax,0x9000
00000003  90                nop
00000004  43                inc bx
00000005  43                inc bx
00000006  CD10              int 0x10

+12

00000000  00909043          add [bx+si+0x4390],dl
00000004  43                inc bx
00000005  CD10              int 0x10

+18

00000000  1090B84F          adc [bx+si+0x4fb8],dl
00000004  0D9090            or ax,0x9090
00000007  FEC4              inc ah
00000009  90                nop

(outras compensações são apenas repetições acima)

+58

00000000  10909090          adc [bx+si-0x6f70],dl
00000004  C3                ret
cópia de
fonte
7

Resposta Unária:

000000 ... 00000

^ 44391 Zeros

Programa Cat. Não importa como você gire, é o mesmo programa.

Walpen
fonte
6

PHP

Aqui está, um programa PHP válido:

Is this still funny?
um cara triste
fonte
2
você deveria ter usado uma palavra como "comeu" (tenho certeza de que há outras), para que cada mudança de caractere ainda seja uma palavra real.
Peter
10
Eu não tenho certeza se um presente ou -1 isso
Lie Ryan
6

Scala

Citações aninhadas:

""""""""""""""""""""""""""""""""

C ++ / Java / C # / Scala

Comente:

///////////////////////////////////

Comando vazio:

;;;;;;;;;;;;;;;

Bater

Combinação de comentário, espaço em branco e shell incorporada:

#

:

Sed

Comandos válidos independentes:

p P n N g G d D h H

Uma combinação dos anteriores:

p;P;n;N;g;G;d;D;h;H;

AWK

Para imprimir todas as linhas do arquivo:

1

ou

//

Não imprima nada:

0

Perl

abcd
Prince John Wesley
fonte
Parece-me que o SED falharia em qualquer rotação estranha? É ;P;n;N;g;G;d;D;h;Hválido?
Captncraig
@ CMP: sim, é válido.
Prince John Wesley
5

J

Primeiro, um script para verificar rotações válidas de um programa s:

check =: 3 :'((<;(". :: (''Err''"_)))@:(y |.~]))"0 i.#y'

Por exemplo, o programa +/1 5(soma de 1 e 5) fornece:

 check '+/1 5'
┌───────┬───┐
│┌─────┐│6  │
││+/1 5││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││/1 5+││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││1 5+/││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││ 5+/1││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││5+/1 ││   │
│└─────┘│   │
└───────┴───┘

Então, um programa chato e válido:

check '1x1'
┌─────┬───────┐
│┌───┐│2.71828│ NB. e^1
││1x1││       │
│└───┘│       │
├─────┼───────┤
│┌───┐│       │ NB. Value of variable x11
││x11││       │ 
│└───┘│       │
├─────┼───────┤
│┌───┐│11     │ NB. Arbitrary precision integer
││11x││       │
│└───┘│       │
└─────┴───────┘
Eelvex
fonte
2

dc

programas dc são facilmente válidos em qualquer rotação. Por exemplo:

4 8 * 2 + p  # 34
8 * 2 + p 4  # stack empty / 10
...
Eelvex
fonte
1

Código da máquina

Que tal o código de máquina Z80 / Intel 8051 para NOP .

Claro que não faz nenhuma operação, mas leva um ciclo ou dois ... você pode ter quantos deles desejar.

E eu discordo da resposta Ruby acima - acho que um único byte 00h é mais curto que um Ruby p.

Richard Le Mesurier
fonte
1

k

.""

Avalia uma sequência vazia

"."

Retorna um caractere de ponto

"".

Retorna a aplicação parcial de '.' (forma diânica) para uma lista de caracteres vazia.

skeevey
fonte
1

sh bash

cc
cc: no input files

cc rodado é cc novamente, mas não é muito amigável se chamado assim.

dh 
dh: cannot read debian/control: No such file or directory
hd 

dh debhelper também não é muito cooperativo, enquanto o hexdump espera apenas pela entrada.

gs
sg 

O Ghostscript inicia o modo interativo, enquanto o grupo de switches mostra uma mensagem de uso - uma solução válida aqui também.

E aqui está o script para encontrar candidatos para esses programas:

#!/bin/bash
for name in /sbin/* /usr/sbin/* /bin/* /usr/bin/*
do 
    len=${#name}
    # len=3 => 1:2 0:1, 2:1 0:2
    # len=4 => 1:3 0:1, 2:2 0:2, 3:1 0:3
    for n in $(seq 1 $((len-1)))
    do
        init=${name:n:len-n}
        rest=${name:0:n}
        # echo $init$rest
        which /usr/bin/$init$rest 2>/dev/null >/dev/null && echo $name $init$rest $n
    done 
done

Se encontrar sequências mais longas também, como (arj, jar) ou (luatex, texlua), que não são válidas após cada turno, mas somente após alguns turnos, que eu interpretei errado no começo, mas há poucas, então é fácil para filtrá-los manualmente.

Usuário desconhecido
fonte
Os exemplos de mais de duas letras não são válidos; o OP disse que "o programa deve ser válido após qualquer mudança circular". Portanto, arj/ jarnão é válido, pois não há rjacomando (embora eu goste deste exemplo). +1 para o script - ótima ideia :) #
Cristian Lupascu
Como não tinha certeza, e não sou um falante nativo de inglês, consultei um dicionário, onde achei ambíguo, quer dizer every, quer dizer a random one. O exemplo com shift left by 6, left by 1e right by 10me garantiu na interpretação, que eu só preciso encontrar uma possibilidade de mudança única.
usuário desconhecido
Não é ambíguo. Se um programa precisar ser válido após algum turno aleatório, ele também deverá ser válido para todos os turnos possíveis.
Griffin
@ Griffin: Ok - você escreveu a pergunta. Eu removi os exemplos mais longos; felizmente, existem suficientes prpt crptc abbrv no unix, como gs e sg. :) Btw .: Você é um falante nativo de inglês? Na frase anterior, você escreveu ... in any language ... - minha solução só funciona no bash (e sh, zsh, ash e mais algumas), mas todas essas outras soluções também usam nomes de programas.
usuário desconhecido
0

Exemplo de Python trivial:

"a""b""c""d""e""f""g""h""i""j""k""l""m""n""o""p""q""r""s""t""u""v""w""x""y""z""";print

Pode ser trocado três caracteres repetidamente para revelar cada vez mais o alfabeto.

Walpen
fonte
Desculpe, eu deveria ter deixado minha pergunta mais clara. Qualquer turno deve produzir um programa válido. Eu atualizei a pergunta.
Griffin
0

Pitão

123456789.0

Apenas avalie alguns números

MrD
fonte
0

dc já está sendo usado, mas o programa a seguir sempre gera o mesmo , independentemente da rotação: D

d

saídas

dc: stack empty
daniero
fonte