Todos os quadrados que correspondem a uma sequência curinga [fechado]

9

Isso foi inspirado em parte do problema da equipe # 6 da competição ARML de 2016.

Aqui está o desafio:

Você recebe uma "sequência curinga", que é uma sequência de dígitos e outro caractere. Uma sequência corresponde a essa sequência curinga pelo seguinte pseudocódigo:

w = wildcard
s = string
# s matches w iff
for all 0 >= i > wildcard.length, w[i] == '?' or s[i] == w[i]

Onde '?' é um personagem de sua escolha.

Em termos de regex, imagine o '?'que é '.'.

O desafio é encontrar todos os números quadrados (o requisito é de até 1 milhão) cujas representações de cadeias decimais correspondem a essa sequência curinga. O "caractere curinga" pode ser qualquer caractere ASCII de sua escolha, desde que não seja um dígito, obviamente.

Por exemplo, 4096corresponde 4**6e 4*9*mas 4114também não.

Entrada

A entrada será fornecida como uma sequência correspondente ao regex [0-9?]+. Pode ser uma cadeia de caracteres, uma matriz de caracteres ou uma matriz de bytes dos caracteres em ASCII.

Resultado

A saída será uma lista / conjunto / matriz de números delimitados pelo que você desejar, que são quadrados perfeitos e correspondem à sequência curinga.

Exemplos de entradas válidas:

1234567*90
1234567?90
1234567u90
['1', '2', '3', '4', '5', '6', '7', '*', '9', '0']
[49, 50, 51, 52, 53, 54, 55, 42, 57, 48]
[1, 2, 3, 4, 5, 6, 7, '*', 9, 0]

Exemplos de saídas válidas:

[1, 4, 9]
1 4 9
1, 4, 9
1-4-9

etc.

Especificações

  • Você não pode usar builtins para encontrar uma lista de quadrados em um determinado intervalo
  • As brechas padrão se aplicam
  • Você deve poder gerenciar até 1 000 000 (1 milhão)
  • Se fornecido com a entrada 1******, é correto imprimir [1000000]. Também é correto imprimir[1000000, 1002001, 1004004, 1006009, 1008016, 1010025, ...]
  • Sequências curinga nunca começarão com o caractere curinga; ou seja, eles sempre corresponderão a seqüências de caracteres do mesmo comprimento.

Casos de teste

4**6  ->  [4096, 4356]
1**1  ->  [1521, 1681]
1**  ->  [100, 121, 144, 169, 196]
9****9  ->  [908209, 915849, 927369, 935089, 946729, 954529, 966289, 974169, 986049, 994009]
9*9***  ->  [919681, 929296]
1**0*  ->  [10000, 10201, 10404, 10609, 12100, 14400, 16900, 19600]
9***4  ->  [91204, 94864, 97344]

Ganhando

Submissão mais curta (válida) (de trabalho) até 14 de fevereiro, desempate entre as vitórias mais antigas.

HyperNeutrino
fonte
11
Eu acho que um bom começo para deixar isso mais claro seria especificar que ?deve ser escolhido pelo respondente.
FryAmTheEggman
2
Por que 25uma resposta válida é para, ***mas não para *2*?
Neil
3
Eu acho que isso seria mais limpo se os números nunca tivessem zeros à esquerda, portanto, apenas as seqüências correspondentes de seu comprimento.
Xnor
@ Neil Isso seria um problema com minha própria solução. Vou aceitar a sugestão de xnor.
HyperNeutrino
A entrada pode ser uma matriz de números inteiros de um dígito e o caractere especial, como {4, "w", "w", 6}(ou melhor ainda {4, w, w, 6}), em vez de uma matriz de caracteres, como {"4", "w", "w", "6"}?
Greg Martin

Respostas:

0

05AB1E , 22 bytes

Provavelmente, há muito espaço para melhorias aqui.
Qualquer não dígito é aceito como curinga.

3°LnvyS¹)ø€Æ0QPyg¹gQ&—

Experimente online!

Explicação a seguir após mais golfe.

Emigna
fonte
Isso parece funcionar para todas as entradas. Bom trabalho.
precisa saber é o seguinte
1

Mathematica, 44 bytes

Print@@@IntegerDigits[Range@1*^3^2]~Cases~#&

A entrada é uma lista de dígitos com um _(sem aspas) como curinga. por exemplo{4, _, _, 6}

Explicação

Range@1*^3

Gerar lista {1, 2, 3, ... , 1000}

... ^2

Quadrado. (lista de todos os quadrados de 1 a 1.000.000)

IntegerDigits[ ... ]

Divida cada quadrado em uma lista de dígitos.

... ~Cases~#

Encontre os que correspondem ao padrão especificado pela entrada.

Print@@@ ...

Imprima-os.

JungHwan Min
fonte
Isso parece funcionar para todos os casos de teste. Bom trabalho.
HyperNeutrino
1

Braquilog , 23 bytes

@e:{@$|,}a#0:{c.~^#I,}f

Experimente online!

Explicação

@e                        Split into a list of characters
  :{@$|,}a                Replace each digit char by the corresponding digit, and each things
                            that are ot digits into variables
          #0              All elements of the resulting list must be digits
            :{       }f   Output is the result of finding all...
              c.            ...concatenations of those digits which...
               .~^#I,       ...result in a number which is the square of an integer #I

Formato de entrada diferente, 13 bytes

Dependendo do que você considera válido como entrada, você pode fazer o seguinte:

#0:{c.~^#I,}f

Experimente online!

que é basicamente a segunda parte da resposta acima, com uma lista como entrada contendo dígitos e variáveis ​​onde estão os caracteres curinga.

Eu não considero isso válido, porque existem apenas 26 nomes de variáveis ​​no Brachylog (letras maiúsculas), portanto isso não funcionaria se você tivesse mais de 26 wilcards.

Fatalizar
fonte
Isso parece funcionar para todas as entradas. Bom trabalho. No entanto, consideraria 24 bytes porque é necessário um argumento de 1 byte. Não sei ao certo como a pontuação para isso funcionaria.
HyperNeutrino
11
@AlexL. O argumento está lá apenas para informar o nome da variável de saída (você pode usar outra letra maiúscula, se desejar). Isso é semelhante às respostas em Prolog / languages ​​com funções em que o predicado / função é nomeado, mas na verdade você não conta os bytes que usa quando o chama.
Fatalize
OK. Não tenho certeza se alguém deve pontuar como 24, já que o argumento é necessário (caso contrário, apenas retorna true.), mas eu não usei idiomas que exigem isso antes. Vou tentar encontrar alguma referência para determinar como devo pontuar isso, mas faria sentido pontuar como 23, então continuarei assim.
precisa saber é o seguinte
1

Perl 6 , 30 26 bytes

Obrigado a @ b2gills por -4 bytes!

{grep /^<$_>$/,map * **2,^1e4}

{grep /^<$_>$/,(^1e4)»²}

Usa o ponto como caractere curinga, para que a entrada possa ser usada como um regex:

{                            }   # a lambda
                         ^1e4    # range from 0 to 9999
               map * **2,        # square each value
 grep /      /,                  # filter numbers that match this regex:
        <$_>                     #   lambda argument eval'ed as sub-regex
       ^    $                    #   anchor to beginning and end

Experimente online .

Uma variante que aceita o asterisco como curinga (conforme sugerido por uma revisão anterior da descrição da tarefa) seria de 42 bytes:

{grep /^<{.trans("*"=>".")}>$/,(^1e4)»²}
smls
fonte
Atualizei as regras e você pode escolher qualquer caractere curinga. Estou marcando isso como 38 bytes.
precisa saber é o seguinte
Hum, como você usa isso? Não sei nada sobre Perl.
HyperNeutrino 13/01
@AlexL .: Obrigado, atualizei a resposta (e adicionei uma explicação também). É uma lambda; você pode chamá-lo diretamente (por exemplo { ... }("9*9***")) ou atribuí-lo a uma variável / símbolo para uso posterior. Observe que o Perl 6 é um idioma separado do Perl, portanto, não funcionará com um intérprete do Perl.
SMLS
Eu costumava sudo apt-get install rakudoter um suposto intérprete Perl6 ... Quando coloco perl6como comando no meu terminal, ele inicia o que parece ser um intérprete Perl6, mas não sei como usá-lo. Eu sei que é um lambda, mas não sei como chamá-lo.
HyperNeutrino
@AlexL .: Adicionei um link "Experimente online", que mostra como um script completo que você pode executar perl6 foo.p6. Você também pode testá-lo em um oneliner shell, comoperl6 -e 'say {grep /^<$_>$/,map * **2,^1e4}( "9.9..." )'
SMLS
1

Ruby, 54 bytes

Função que recebe um argumento de cadeia. Experimente online.

->s{(0..1e3).map{|i|"#{i**2}"[/^#{s.tr ?*,?.}$/]}-[p]}
Value Ink
fonte
Você pode salvar um byte usando i * i em vez de i ** 2
GB
Isso não parece funcionar porque o segundo #está fazendo um comentário ao restante da linha.
HyperNeutrino
@AlexL Oh, funciona bem. repl.it/FJCV
Valor Ink
ohhhh ok, eu simplesmente não sabia como testar Ruby. Me desculpe. Isso parece funcionar para todas as entradas. Bom trabalho!
precisa saber é o seguinte
0

Lote, 109 bytes

@for /l %%i in (0,1,999)do @set/aj=%%i*%%i&call copy nul %%j%%.%%j%%$>nul
@for %%s in (%1.%1$)do @echo %%~ns

Usa ?como curinga. Funciona criando 1000 arquivos. O nome do arquivo é o número do quadrado e a extensão do arquivo é o número do quadrado com um $sufixo. Isso ocorre porque a correspondência de padrões do Lote conta à direita de ?s como opcional, portanto 1?corresponderá a ambos 1e 16; o $que força a partida a ser exata. No entanto, não queremos $produzir o arquivo, apenas produzimos o nome do arquivo apenas sem extensão.

Neil
fonte
0

JavaScript (ES6), 68 66 bytes

EDIT: Atualizei minha solução abaixo depois de me inspirar na resposta de JungHwan Min . Agora é compatível com ES6.

Recebe a entrada no formato em '1..4'que .está o curinga.

Em vez de iterar para 1e6 e o ​​enraizamento quadrado, este itera para 1e3 e quadrados.

p=>[...Array(1e3)].map((_,n)=>''+n*n).filter(n=>n.match(`^${p}$`))

JavaScript (ES7), 71 69 bytes

p=>[...Array(1e6).keys()].filter(n=>n**.5%1?0:(''+n).match(`^${p}$`))

Cria uma matriz de números de 0 a 1e6 e depois a filtra por números que são quadrados e correspondem ao padrão.

É terrivelmente lento porque sempre interage com 1e6.

George Reith
fonte
Eu não acho que **está funcionando, porque está me dando um "SyntaxError: expected expression, got '*'".
HyperNeutrino
@AlexL. As regras parecem ter mudado. As regras anteriores sugeriram que eu pudesse escolher o caractere curinga.
George Reith
Você só precisa suportar até 1e6...
HyperNeutrino
Além disso, mudei as regras novamente; o problema não está nas regras, é porque o **operador não existe, pelo menos não no meu sistema.
HyperNeutrino
@AlexL. Ah, desculpe, eu pensei que você quis dizer a entrada **. Sim, é ES7 Eu irei atualizar o título aqui está uma lista de navegadores suportados atualmente developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
George Reith
0

Perl, 42 45 38 bytes

EDIT: esclarecimento por Alex, podemos usar o período como caractere curinga que corta a operação y //.

perl -pe 's|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

EDIT: solução que usa o asterisco como caractere curinga e espera a sequência curinga em STDIN

perl -pe 'y/*/./;s|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

Este deixa, sem dúvida, muito espaço para melhorias, é bem direto. A expressão curinga é esperada como argumento de linha de comando, com o caractere curinga de período (o que mais?).

say"@{[grep/^$ARGV[0]$/,map$_*$_,1..1e3]}"
daniel
fonte
A pergunta especifica que os curingas são dados como asteriscos. Uma revisão anterior da pergunta permitiu escolher seu próprio caractere curinga?
SMLS
11
@smls: a pergunta ainda especifica a escolha do seu curinga, embora não esteja na seção de regras: O caractere usado como curinga não precisa necessariamente ser um asterisco, pode ser qualquer caractere ASCII de sua escolha, desde que não é um dígito, obviamente.
Emigna
Sim, fiquei confuso com isso. Mais tarde, ele diz claramente que o caractere curinga precisa ser um asterisco. Eu acho que a definição com o regex está levando. Vou revisar minha solução.
Daniel
11
Hm, na verdade, a frase citada por @Emigna é bastante claro que nós podemos escolher o nosso próprio carácter universal, não é?
SMLS
Para esclarecer, o caractere curinga pode ser o que você quiser. Eu acidentalmente errei as regras ao reafirmar a explicação.
precisa saber é o seguinte
0

Python 3-98 97 bytes

import re;print(re.findall(r"\b"+input()+r"\b",("\n".join([str(x*x) for x in range(1,1001)]))))

Requer entrada como '4..6'.

Carra
fonte
Você pode salvar 3 bytes usando import ree re.findall; a otimização com o from...import *realmente não a otimiza nesse caso.
precisa saber é o seguinte
Fornecido 1...., ele fornece 1 4 9e 16 25como respostas válidas, o que não está correto. Corrija seu programa.
precisa saber é o seguinte
Corrija o caso ingressando em "\ n".
Carra
Isso não funciona 1....... Ele retorna [], mas deve dar [1000000]. Isso pode ser corrigido a um custo de 0 bytes usando em range(0, 1001)vez de range(0, 1000).
HyperNeutrino
Bom ponto, acabei de verificar todos os casos de teste a partir da descrição :)
Carra
0

k - 28 caracteres

{s(&:)($:s:s*s:!1001)like x}

Usa ?como o caractere curinga. A likefunção usa ?como curinga e faz uma lista dos primeiros 1001 quadrados (incluindo 1M), converte todos eles em seqüências de caracteres e depois verifica onde eles correspondem ao padrão.

    {s(&:)($:s:s*s:!1001)like x} "1??"
100 121 144 169 196
C. Quilley
fonte
Estou recebendo este erro para ele: type error {s(&:)($:s:s*s:!1001)like x} "1" at execution instance 2 of ":". Você poderia fornecer um link para um conjunto de testes em funcionamento ou verificar se há algum problema?
HyperNeutrino 13/01
@AlexL. Ele funciona para mim em kdb + 's modo k
C. Quilley
Hmm. Vou tentar testá-lo com diferentes intérpretes.
precisa saber é o seguinte
0

utilitários bash + Unix, 33 bytes

dc<<<'0[2^pv1+lax]dsax'|grep ^$1$

Isso usa '.' como o caractere curinga.

O programa dc imprime os números quadrados em um loop infinito:

0     Push 0 on the stack.

[     Start a macro (called a).

2^    Square the number at the top of the stack.

p     Print the number at the top of the stack, followed by a newline.

v     Replace the number at the top of the stack (a square number) with its square root.

1+    Increment the number at the top of the stack.

lax   Run the macro again (looping).

]     End of the macro.

dsax  Store the macro in register a and run it.

A saída dc é canalizada para grep, que imprime apenas os quadrados que correspondem ao padrão necessário.

Isso funciona quando eu o executo em um sistema Linux ou OS X real (mas não funciona no TIO, provavelmente porque o programa dc tenta se recuperar para sempre, e eu suspeito que o TIO fique sem espaço de pilha para a recursão e / ou um problema com o tubo sem fim).

Mitchell Spector
fonte
Estou executando isso com o Linux Mint 17.3 Rosa e não está finalizando. Eu acho que o problema está no dccomando interminável .
precisa saber é o seguinte
Eu suspeito que é realmente o buffer que está causando o problema. Eu não tenho essa versão do Linux, mas você pode tentar substituir o grep por grep --line-buffered (para fazer com que cada linha seja impressa conforme é grepped). [Claro, que adiciona um número de bytes.]
Mitchell Spector
Eu adicionei o argumento grep, mas não faz diferença. Tentei colocar o --line-bufferedde ambos os lados ^$1$, mas não funciona de qualquer maneira.
precisa saber é o seguinte
@ AlexL. Obrigado por tentar. Não sei se a diferença está no kernel ou na versão bash que estou executando. Consegui fazê-lo funcionar no TIO forçando o fim da entrada do grep usando head, da seguinte maneira: dc <<< '0 [2 ^ pv1 + lax] dsax' | head -1 sed s/./0/g<<<$1| grep ^ $ 1 $ Isso usa o comprimento do padrão para limitar os números que estão sendo testados (padrões de 4 caracteres verificam apenas até 9999, etc.). Aqui está um link do TIO: tio.run/nexus/…
Mitchell Spector
Obrigado pela correção. Eu não acho que a solução atual realmente funcione (embora eu não tenha muito conhecimento de bash), porque parece que ele precisa calcular todos os valores antes de alimentar isso grep. No entanto, como atualmente não é a solução mais curta, vou mantê-lo em 33 bytes para pontuação. Parece funcionar para todas as entradas, bom trabalho!
HyperNeutrino