Multiplicação por auto-modificação

33

... pelo menos para alguma definição de "auto-modificação".

A tarefa

Neste desafio, sua tarefa é escrever três cordas A, Be Cque satisfaçam as seguintes propriedades.

  • A cadeia Btem comprimento pelo menos 1.

  • Para todos n ≥ 0, a string é um programa válido (ou seja, programa executável completo ou definição de função) na sua linguagem de programação preferida. A repetição denota sobrescritos, então isso significa que as cordas , , , etc. Cada programa tem uma string como entrada e retorna uma seqüência de caracteres como saída.ABnCACABCABBCABBBC

  • Para qualquer m, n ≥ 0, se o programa for executado com entrada , ele retornará . Para entradas não deste formulário, o programa pode fazer qualquer coisa, incluindo falha.ABmCABnCABm*n+1C

Alguns exemplos no formato program(input) -> output:

AC(AC) -> ABC
ABC(AC) -> ABC
ABBBBBC(AC) -> ABC
AC(ABC) -> ABC
AC(ABBBBC) -> ABC
ABC(ABC) -> ABBC
ABBC(ABC) -> ABBBC
ABBBBC(ABBBC) -> ABBBBBBBBBBBBBC
ABBBC(ABBBBBBC) -> ABBBBBBBBBBBBBBBBBBBC

Regras e Pontuação

Sua pontuação é o comprimento total AeC , quanto menor a pontuação, melhor. Observe que, embora Bnão seja contado para a pontuação, ela deve ser produzida por Ae Ccomo no primeiro exemplo.

As brechas padrão não são permitidas. Os programas não têm permissão para acessar direta ou indiretamente seu próprio código-fonte (exceto quando forem fornecidos como entrada). Você é obrigado a identificar as seqüências de caracteres e A, de alguma forma, na sua resposta, e é incentivado a explicar sua solução.BC

Zgarb
fonte

Respostas:

16

CJam, 9 8 bytes

A: 1
B: 0
C:  r,(#0q

Experimente online no intérprete CJam .

Como funciona

(ABcode) e# Push the integer 10 ** len(Bcode).
<SP>     e# Noop. Separates (AB) and C for input reading.
r        e# Read the first whitespace-separated token from STDIN (ABinput).
,(       e# Push the string length minus 1: len(Binput)
#        e# Power operator: 10 ** len(Bcode) len(Binput) # ->
         e#   (10 ** len(Bcode)) ** len(Binput) = 10 ** (len(Bcode) * len(Binput))
0        e# Push an additional 0 to complete len(Bcode) * len(Binput) + 1 zeroes.
q        e# Read the remaining input (C).
Dennis
fonte
12

CJam, 15 13 11 bytes

A: rl"
B: <SP>
C: <LF>",(*SNq

Experimente online no intérprete CJam .

Como funciona

e# A

r     e# Read a whitespace-separated token from STDIN.
      e# This reads the input up to the first space, but does not consume it.
l     e# Read the rest of the first line from STDIN.
      e# This reads up to the first linefeed and consumes it.

"     e# Initiate a string.

e# B

<SP>  e# Fill the string with as many spaces as there are copies of B.

e# C

<LF>" e# Terminate the string with a linefeed.
      e# This serves as a delimiter for the `l' command.
,(    e# Compute the length of the string minus 1 (to account for the LF).
*     e# Repeat the string read by `l' that many times.
SN    e# Push a space and a linefeed.
q     e# Read the remaining input (i.e., the second line) from STDIN.

No final, a pilha contém o token lido r, o espaço produzido *, o espaço e o avanço de linha pressionados SNe a linha lida q. CJam imprime tudo isso automaticamente.

Dennis
fonte
Hah, bom uso de citações lá: D
Optimizer
9

Pitão, 10

A: w*\0hl*w[<newline>
B: 0
C: <empty>

Dividimos a fonte em duas linhas. A primeira linha é A, a segunda linha são as Bs. Como A está na primeira linha, a primeira wapenas imprime A - fácil, pronto.

Em Pyth, os zeros à esquerda são tokens separados, o que [00)realmente é [0, 0]. Observe que a primeira linha termina em l[e a segunda linha consiste em 0000.... Então, l[na verdade, conta o número de Bs neste programa. A segunda wlê na segunda linha da entrada - este é o número de Bs da entrada. A partir daqui, é simples multiplicar, incrementar e gerar muitos zeros.

orlp
fonte
9

Retina , 25 19 bytes

A: ]\]<LF>
B: ]]
C: <LF>m`^]*$<LF>]$0]

<LF> stands for newline

ABCCódigo de exemplo :

]\]
]]
m`^]*$
]$0]

O código possui duas etapas de substituição:

  • mudar a entrada AB^mCem AB^(m*n)Calterando cada Bpara B^n:

    • ]\]corresponde a cada Bentrada e nada mais, graças ao escape nas linhas do padrão
    • ]]...]] é B^n
  • mudar B^(m*n)para B^(m*n+1)por

    • m`^]*$tomando a linha com apenas ]'s
    • ]$0]adicionando um par extra ]]para que essa linha não corresponda ao primeiro regex

Adicionei 3 bytes à pontuação para o -ssinalizador de várias linhas, necessário para que todo o código da Retina pudesse estar em um arquivo.

2 bytes salvos graças ao @ MartinBüttner.

randomra
fonte
8

Python 3, 51 bytes

A: lambda s:s[:28]+"x"*(1+len("
B: x
C: ")*(len(s)-51))+s[-23:]

Exemplo de uso:

>>> f=lambda s:s[:28]+"x"*(1+len("xx")*(len(s)-51))+s[-23:]
>>> f('lambda s:s[:28]+"x"*(1+len("xxx")*(len(s)-51))+s[-23:]')
'lambda s:s[:28]+"x"*(1+len("xxxxxxx")*(len(s)-51))+s[-23:]'

A função calcula n*m+1com (1+len("xxx")*(len(s)-51))onde há m xa string ( xxxparte é a B^m). Multiplicar a string "x"com esse número fornece B^(n*m+1)e a função retira Ae Csai da entrada e concatena tudo isso para obter AB^(n*m+1)C.

A mesma abordagem em J:

J, 35 bytes

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]
randomra
fonte
5

CJam, 22

A:<empty>
B:{])`\,q,K/(*))*"_~"}
C:{])`\,q,K/(*))*"_~"}_~

Exemplo de execução:

ABBC(ABC) -> ABBBC

que se traduz em

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

com entrada como

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

que fornece a seguinte saída:

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Como funciona :

Vamos dar uma olhada em quais programas ACe ABCcomo:

AC :{])`\,q,K/(*))*"_~"}_~
ABC:{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Percebemos que C=B_~

Vamos analisar o que Bestá fazendo:

{])`\,q,K/(*))*"_~"}

{                  }    e# This is a code block. Alone, this does nothing except
                        e# pushing this block to stack as is
 ]                      e# Wrap everything on stack in an array
  )`                    e# Take out the last part and convert it to its string representation
    \,                  e# Take length of remaining array
      q,K/              e# Read the input, take its length and int divide by K (i.e. 20)
          (*            e# Decrement and multiply by the array length on stack
            ))          e# Add two to the product
              *         e# Repeat the string representation on stack that many times
               "_~"     e# Put this string on stack

Agora vamos ver o que a execução ACsem nenhuma entrada fará:

{])`\,q,K/(*))*"_~"}_~                      e# Copy the block and run it
{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}~   e# Block is copied, run it
{      ...         } ])                     e# Wrapped array has the block in it.
                       `\,                  e# Stringify it and take length of remaining = 0
                          q,K/              e# No input so 0
                              (*))          e# 0 * -1 = 0. 0 + 2 = 2
                                  *         e# Repeat the stringified block 2 times:
                                            e# "{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}"
                                   "_~"     e# Put this string. Program ends, so print stack:
                                            e# {])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Uau, a saída é ABC.

Basicamente, contamos quantos Bexistem no código. Em seguida, quantos estão na entrada (usando comprimento). Multiplique-os, aumente duas vezes (já que Ctambém possui B) e acrescente _~para obterC

Experimente online aqui

Optimizer
fonte
3

Haskell , 50 bytes

fé uma função que leva e retorna a String.

A string B é apenas um espaço único, enquanto C começa com um.

A:_:b="
B: 
C: ";f s|a:c<-words s=unwords$a:(drop 50s>>b):c

Experimente online!

  • _:b=" "cessionários todos, mas o primeiro dos espaços na string literal para b, fazendo que igual ao do programa m cópias B.
  • sé a sequência de entrada. a:c<-words sdivide-o em palavras separadas por espaço, para que ase torne A e cse torne uma lista das palavras que compreendem C. As cópias B são ignoradas, uma vez que wordsespremem vários espaços (o que o restante do programa evita).
  • drop 50sé uma sequência com comprimento igual ao número n de B cópias na entrada. drop 50s>>bconcatena muitas cópias de b, dando espaço para o manganês .
  • unwords$a:(drop 50s>>b):cjunta todas as cordas de volta com espaços. Como há uma "palavra" extra (drop 50s>>b)inserida na lista, também há um espaço de junção extra, adicionando automaticamente o +1 à multiplicação.
Ørjan Johansen
fonte
2

Matlab, 85

A primeira vez que fiz um desafio tão abstrato, então para mim foi mais um desafio de codificação do que um desafio de golfe com código!

As três strings são, sem as aspas:

A:    "X=strsplit(input('','s'));m=0 "
B:    "+1 "
C:    ";[X{1},32,repmat(['+1',32],1,m*(length(X)-2)+1),X{end}]"

Como funciona: divido o argumento de entrada em espaço em branco, para que npossa ser determinado a partir do número de partes da string. B funciona como uma espécie de contador para obter m. Para reconstruir a resposta que eu uso A e C da divisão, repita B m * n + 1 vezes e insiro os espaços usando seu valor ASCII, para que nenhuma divisão indesejada ocorra em C.

EDIT: gritos, acidentalmente contados A + B

Oebele
fonte
1

C (gcc) , 81 bytes

O requisito de identificar as strings parece estar em desacordo com o fato de termos um comportamento arbitrário permitido para entrada ilegal, a menos que tenhamos padrões bastante relaxados do que a identificação implica. Naturalmente, tomei a interpretação que lança mais bytes.

Experimente online!

A: m;f(char*s){m=strrchr(s+66,32)-s-65;printf("%.66s%*s",s,m*strlen("
B: <SPACE>
C: ")+16,s+m+66);}
gastropner
fonte
Pela identificação Eu só quis dizer que deve ficar claro a partir de sua resposta que trechos de código são A , B e C . Não é um requisito para o programa.
Zgarb 28/07/19
1

TI-Basic (série 83), 65 bytes

Segmento A (33 bytes):

Input Str1:sub(Str1,1,27:For(I,0,(length(Str1)-55)(length("

Segmento B:

X

Segmento C (32 bytes):

Y")-1:Ans+"X":End:Ans+sub(Str1,length(Str1)-27,28

Estou realmente empolgado em encontrar esse desafio de qualidade! A maioria dos quines não funciona no TI-Basic sem pelo menos um pouco de trapaça, porque não há como escapar do "símbolo. (Nos dois sentidos da palavra "escape".) Mas aqui, obtemos uma string de entrada por meio do Inputcomando, e digitar um "lá é perfeitamente adequado.

Ainda há uma certa bobagem do TI-Basic por aqui: uma string vazia é inválida; portanto, a solução ingênua de inserir a string "XXX...XX"em um loop não funcionará quando n = 0. Em vez disso, calculamos manualmente o valor de mn + 1 e inserimos a string "X"várias vezes.

As constantes mágicas 27e 28no programa são ligeiramente fora a partir das contagens de bytes 33 e 32, por causa Str1, sub(, e length(são símbolos de dois bytes que apenas contribuem 1 ao comprimento de uma cadeia de caracteres.

Se usarmos novas linhas em vez de :, parece que é possível salvar alguns bytes deixando de lado as aspas finais, mas na verdade isso não funciona. Primeiro de tudo, você precisa de um editor hexadecimal antes de adicionar o caractere de nova linha em uma string: não é possível digitar apenas porque, se você pressionar ENTER durante um Inputcomando, ele enviará a entrada. Quando tentei a abordagem do editor hexadecimal, acabei recebendo um erro estranho de estouro de buffer que modificou o conteúdo do meu programa; portanto, não tente fazer isso em casa com sua calculadora cara.

Misha Lavrov
fonte
0

Java 11, 135 65 + 26 = 91 bytes

UMA

s->{var p=s.split("\\(\"|\"\\.");return p[0]+"(\"B"+p[1].repeat("

B

B

C

".length())+'"'+'.'+p[2];}

Experimente on-line aqui (o TIO ainda não possui o Java 11, portanto, ele conta com um método auxiliar em vez de String::repeat()).

Ungolfed:

s -> { // lambda taking and returning a String
    var p = s.split("\\(\"|\"\\."); // split input into parts A, B^n, C (where n may be 0) at the "(\"" and "\"."
    return p[0] + "(\"B" + // put it back together: A plus the part the split shaved off, plus an extra B ...
    p[1].repeat("BBB".length()) + // ... plus B^(n*m)
    '"' + '.' + p[2]; // plus C, with the part the split shaved off reattached
}
OOBalance
fonte