Números unários geralmente representam apenas números inteiros não negativos, mas podemos estendê-los para representar todos os números inteiros da seguinte maneira:
- Um número inteiro positivo N é representado como N
1
's:5 -> 11111
- Um número inteiro negativo -N é representado como um
0
seguido por N1
's:-5 -> 011111
- Zero é representado como
0
Podemos então representar uma lista desses números sem ambiguidade, se usarmos 0
como separador:
3,-2,0,1
111,011,0,1
111 0 011 0 0 0 1
11100110001
Sua tarefa: pegue uma sequência representando uma lista de números unários assinados e traduza-a em uma lista de números decimais.
Detalhes
Você pode assumir que a entrada é uma lista completa de números unários assinados. Em particular, seu programa não precisará lidar com 1) entrada vazia ou 2) entrada que termina com um separador.
Você pode supor que a magnitude de cada número não exceda 127. Para idiomas com tamanhos máximos de strings ou listas, você pode supor que a entrada e a saída se encaixem nas estruturas de dados do seu idioma, mas seu algoritmo deve teoricamente funcionar para uma lista de qualquer tamanho.
Seu programa ou função pode executar E / S de qualquer uma das maneiras padrão . A entrada pode ser uma sequência ou uma lista de caracteres, seqüências de caracteres únicos, números inteiros ou booleanos. Você pode usar dois caracteres para representar 1
e 0
; se você não usar 1
e 0
, especifique quais caracteres você está usando.
A saída deve ser números decimais em qualquer formato razoável de lista (em particular, deve haver algum tipo de separador entre números). Os números negativos devem ser indicados com um sinal de menos, embora, se o seu idioma tiver um formato diferente para números inteiros negativos, eu também o aceite. Zero pode ser representado na saída como 0
ou -0
.
Casos de teste
1 -> 1
0 -> 0 (or -0, and similarly for the other test cases)
011 -> -2
1101 -> 2,1
1100 -> 2,0
11001 -> 2,-1
110001 -> 2,0,1
11100110001 -> 3,-2,0,1
00000001 -> 0,0,0,-1
01111011111111001111111111111110111111111111111100111111111111111111111110111111111111111111111111111111111111111111 -> -4,8,-15,16,-23,42
01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -> -127
'0's
, não é tecnicamente unário. Bom desafio!0
) e o prefixo do sinal negativo (0
) sejam os mesmos, embora ainda sejam inequívocos, pois você não pode ter sinais negativos no meio de um número (é182--693-1
um número? Não, e nem é1111011000101111
exatamente pelo mesmo motivo).Respostas:
Python 2 ,
7370 bytesUma função que recebe uma string como entrada e retorna uma representação de string de uma lista Python. Zero pode ser representado por
0
e-0
(na última vez):Explicação
split
a sequência de entradas
nos zeros.map
).Isso nos leva um longo caminho. Os zeros eram separadores, afinal. E os números eram unários, de maneira
len
conveniente os converte em decimal. Mas agora nós estragamos todos os usos não separadores de0
. Felizmente, todos os usos que não eram do separador estavam levando zeros, então eles vieram depois de um separador-zero e nos deram cadeias de comprimento zero ('00'.split('0') == ['', '', '']
). Essas cadeias de comprimento zero também se tornaram0
por causa dolen
.replace
cada zero que precede outro número por um sinal negativo nesse número. Isso corrige o uso de0
como um sinal, mas quebra os zeros literais. Os zeros literais também foram precedidos por um separador; portanto, eles agora se tornaram pares de traços extras no próximo número.replace
cada um de--
volta em um0
elemento na "lista".fonte
Retina ,
2321 bytesExperimente online!
O primeiro estágio
(.)0<newline>$1<space>
corresponde a qualquer caractere seguido de a0
. A partida é substituída pelo primeiro caractere seguido por um espaço. Isso divide a string nos números individuais.O segundo estágio
01<newline>-1
substitui0
's antes de um bloco de1
' s para a-
placa.O último estágio
1+<newline>$.&
corresponde a todos os blocos de1
's e os substitui pelo comprimento do grupo.Aqui está um exemplo com a saída dos estágios individuais.
fonte
Vim, 56 bytes
Experimente online!
Eu não publico no vim há algum tempo. Eu estou usando principalmente o vim porque V às vezes é uma dor. Como o
count
comando, perfeito para colocar o número de '1's na linha, substituirá qualquer' 0 'na linha, portanto, não podemos negá-lo posteriormente.Explicação:
Este é um byte mais curto que o simples:
devido ao encadeamento de comandos. Como esse separa os comandos, eu o usarei para a explicação.
Agora, cada número unário assinado está em uma linha individual. Usando '11100110001' como exemplo, neste momento teremos:
Como adicionamos novas linhas ao final de cada partida, tínhamos uma linha vazia antes de executá-la. Depois de executar isso, teremos um '0' (porque corresponde a uma execução de 0 '1). Então chamamos
D
para excluir esta linha, deixando em brancofonte
:%s/1+$/
você obteria um byte menor se não fosse a necessidade de barra invertida a+
:(-
vez de0
ou-0
Haskell ,
6866 bytesExperimente online! Aceita entrada como uma lista de zeros e uns. Exemplo de uso:
f [0,0,0,1,1]
rendimentos[0,-2]
.Explicação:
O padrão correspondente em
f(x:r)|(a,b)<-span(>0)r
ligax
- se ao primeiro elemento da entrada,a
a uma lista (potencialmente vazia) dos seguintes1
s eb
ao restante da entrada. Dada uma entrada[0,1,1,1,0,0,1]
, obtemosx=0
,a=[1,1,1]
eb=[0,0,1]
.O número atual é então a soma de
a
negado sex=0
ou a soma dea
mais um sex=1
. Isto é conseguido através da indexação comx
a uma lista que contém uma função negação e incremento, e aplicando a função resultante com a soma dea
:[(0-),(1+)]!!x$sum a
.A lista restante
b
está vazia ou contém um zero separador e o próximo número. A compreensão da lista[z|_:t<-[b],z<-f t]
tenta corresponderb
ao padrão_:t
, ou seja, esquecer o elemento head e vincular o restante da listat
. Seb
estiver vazio, essa correspondência falhará e a compreensão da lista será avaliada[]
, que é o caso base da recursão. Caso contrário, a funçãof
é aplicada recursivamentet
e a compreensão da lista é avaliada para todos os elementosz
do resultado def t
.fonte
Wolfram Language (Mathematica) , 80 bytes
Experimente online!
Abusa do mecânico
StringCases
, pois ele não verifica padrões sobrepostos. Como pesquisamos da esquerda para a direita, sem sobreposições, sempre obtemos apenas os números inteiros necessários.Explicação
Anexar um zero no final
Encontre todos os seguintes padrões ...
Um único caractere (chame-o
x
), seguido pela menor seqüência possível de comprimento zero ou maior (chame-oy
), seguido por um zero.Aplicar ao padrão correspondente: mede o comprimento de
y
. Sex
for zero, negue o valor. Senão, incremente um.Isso também abrange
00
, jáy
que seria uma string vazia e calcularíamos-0
(== 0
).fonte
Flacidez cerebral , 94 (70?) Bytes
Experimente online!
Na verdade, isso é surpreendentemente conciso para o cérebro.
Aqui está uma versão comentada / legível:
Se a saída puder ser inversa, podemos fazer isso por 70:
Essa dica é quase perfeita para essa situação. Mas isso não funciona muito bem, já que precisamos pressionar um 0 antes de fazer a operação (contando os '1s), e a operação acontece em um loop. O mais curto que pude utilizar esta dica é:
que também tem 94 bytes.
fonte
Perl 5 , 40 + 1 (
-n
) = 41 bytesExperimente online!
fonte
Casca ,
20 18 17 1514 bytesExperimente online!
Explicação
A divisão funciona assim.
ġ/
divide seu argumento entre cada par de elementosa,b
para o qual/a b
é falso./a b
é a divisão com argumentos invertidos, entãob
divididos pora
. Os valores relevantes neste programa são estes:/1 1
dá1
(verdade)./1 0
dá0
(falso)./0 1
dáInf
(infinito positivo, verdade)./0 0
dáAny
(um valor especial de NaN, falso).fonte
Acc !! ,
252237 bytesUsos
-0
. Produz números separados por caracteres de tabulação, com uma tabulação à direita.Experimente online!Quantidade de tempo escrevendo o algoritmo real: 20 minutos. Período de depuração do meu código de saída decimal: 45 minutos. : ^ P
Com comentários
Não sei se esses comentários explicam muito bem o código - eles são baseados nas minhas anotações enquanto eu escrevia, então eles assumem alguma compreensão de como Acc !! trabalho. Se algo precisar de mais explicações, entre em contato e tentarei esclarecer as coisas.
fonte
Python 2 ,
9692 bytesExperimente online!
Thx para ovs e DLosc para 2 bytes cada.
fonte
R , 119 bytes
Experimente online!
O código usa esta solução do stackoverflow para um problema relacionado (obrigado aos ciumentos pela ideia). A saída é uma sequência separada por espaço impressa em stdout.
fonte
Geléia ,
1918 bytesDeve haver uma maneira melhor ...
Um programa completo imprimindo cada número seguido de um avanço de linha.
Experimente online!
Quão?
fonte
QBasic,
8886 bytesIsso foi divertido. Várias revisões a partir de uma versão de 107 bytes resultaram em um dos bits mais ofuscados do QBasic que acho que já escrevi. (Edit: Estranhamente, eu consegui jogar 2 bytes, tornando o código mais claro.)
Nota: este programa lê a entrada do usuário, um caractere de cada vez, sem ecoá-lo na tela (resultado do uso em
INPUT$(1)
vez daINPUT
declaração usual ). Portanto, enquanto você digita, não verá os zeros e zeros, mas os números decimais aparecerão conforme são calculados. Certifique-se de baterEnter no final da entrada para ver o último número e finalizar o programa.Versão ungolfed
Explicação
(AKA "O quê? Isso ainda não faz sentido!")
A estratégia básica é executar um loop que agarra um caractere de
INPUT$(1)
cada vez, faz coisas com ele e continua em loop enquanto o personagem tiver um valor ASCII maior que o de!
(ou seja, não era uma nova linha).Nós acompanhamos os números em andamento usando duas variáveis.
num
é o número de caracteres no número unário assinado atual (incluindo qualquer zero inicial).sign
é1
se o número tiver um zero à esquerda,0
caso contrário. Ambos precisam ser inicializados0
, o que é ótimo para a versão golfada porque as variáveis numéricas no QBasic são inicializadas automaticamente para0
.Sempre que lemos um personagem, a primeira coisa é determinar se é
1
ou não0
. Usaremos esse resultado duas vezes, para armazená-loisZero
. Tecnicamente, esse nome é enganador, pois o valor também será verdadeiro se o caractere for uma nova linha. Observe que a verdade no QBasic é-1
e falsey é0
.Agora, se estamos no meio da leitura de um número (
num > 0
) e atingimos o zero ou o final da entrada (isZero
), precisamos calcular qual número terminamos de ler.sign
armazena0
para positivo,1
para negativo. Para obter o1
positivo e o-1
negativo, precisamos1-2*sign
.num
armazena a magnitude correta para positivos, mas uma a mais que a magnitude para negativos (uma vez que inclui o marcador de sinal). Para que possamos usarnum-sign
pela magnitude.Multiplique-os e imprima; redefina
sign
enum
para0
em preparação para ler o próximo número.Caso contrário (se não ter atingido um zero, ou se nós batemos um zero no início de um número), atualizamos
sign
enum
como segue:sign
torna-1
se se estamos olhando para um zero à esquerda; caso contrário, se estivermos olhando para um, ele permanece no que já era. O código de golfe és=s-z
, o que equivale à mesma coisa:z
é-1
. Comos
é garantido que será0
(porque este é o início de um novo número),s-z
será1
.z
é0
. Em seguida,s-z
permanece com o valor ques
tinha anteriormente.num
é incrementado.É isso aí!
fonte
JavaScript (ES6), 60 bytes
Retorna uma lista separada por espaços de números inteiros.
Casos de teste
Mostrar snippet de código
fonte
Lua , 58 bytes
Experimente online!
Programa completo, recebe entrada da linha de comando e imprime os números em stdout separados por novas linhas.
fonte