Les nombres unaires ne représentent généralement que des entiers non négatifs, mais nous pouvons les étendre pour représenter tous les entiers comme suit:
- Un entier positif N est représenté par N
1
:5 -> 11111
- Un entier négatif -N est représenté par un
0
suivi de N1
:-5 -> 011111
- Zéro est représenté comme
0
Nous pouvons alors représenter une liste de ces nombres sans ambiguïté si nous utilisons 0
comme séparateur:
3,-2,0,1
111,011,0,1
111 0 011 0 0 0 1
11100110001
Votre tâche: prendre une chaîne représentant une telle liste de nombres unaires signés et la traduire en une liste de nombres décimaux.
Détails
Vous pouvez supposer que l'entrée est une liste complète des numéros unaires signés. En particulier, votre programme n'aura pas à gérer 1) une entrée vide ou 2) une entrée qui se termine par un séparateur.
Vous pouvez supposer que la magnitude de chaque nombre ne dépassera pas 127. Pour les langues avec des tailles maximales de chaînes ou de listes, vous pouvez supposer que l'entrée et la sortie s'adapteront aux structures de données de votre langue, mais votre algorithme devrait théoriquement fonctionner pour une liste de n'importe quelle taille.
Votre programme ou fonction peut effectuer des E / S de n'importe quelle manière standard . L'entrée peut être une chaîne ou une liste de caractères, des chaînes à un seul caractère, des entiers ou des booléens. Vous pouvez utiliser deux caractères quelconques pour représenter 1
et0
; si vous n'utilisez pas 1
et 0
, veuillez spécifier les caractères que vous utilisez.
La sortie doit être des nombres décimaux dans n'importe quel format de liste raisonnable (en particulier, il doit y avoir une sorte de séparateur entre les nombres). Les nombres négatifs doivent être indiqués par un signe moins, bien que si votre langue a un format différent pour les entiers négatifs, je l'accepterai également. Le zéro peut être représenté dans la sortie comme0
ou -0
.
Cas de test
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
, ce n'est pas techniquement unaire. Bon défi cependant!0
) et le préfixe du signe négatif (0
) sont les mêmes, bien que ce soit toujours sans ambiguïté, car vous ne pouvez pas avoir de signes négatifs au milieu d'un nombre (182--693-1
un nombre? Non, et ni1111011000101111
pour la même raison).Réponses:
Python 2 ,
7370 octetsUne fonction qui prend une chaîne en entrée et renvoie une représentation sous forme de chaîne d'une liste Python. Zéro peut être représenté à la fois par
0
et-0
(quand il vient en dernier):Explication
split
la chaîne d'entrées
sur les zéros.map
).Cela nous fait beaucoup de chemin. Les zéros étaient des séparateurs après tout. Et les nombres étaient unaires,
len
convertit donc commodément ceux en décimal. Mais maintenant, nous avons foiré toutes les utilisations non séparatrices de0
. Heureusement, toutes les utilisations sans séparateur étaient des zéros non significatifs, ils sont donc venus après un zéro séparateur et nous ont donné des chaînes de longueur nulle ('00'.split('0') == ['', '', '']
). Ces chaînes de longueur nulle sont également devenues à0
cause dulen
.replace
chaque zéro qui précède un autre nombre par un signe négatif sur ce nombre à la place. Cela corrige l'utilisation de0
comme signe mais brise les zéros littéraux. Les zéros littéraux ont également été précédés d'un séparateur, ils sont donc devenus des paires de tirets supplémentaires sur le numéro suivant.replace
chacun--
retourne dans un0
élément de la "liste".la source
Rétine ,
2321 octetsEssayez-le en ligne!
La première étape
(.)0<newline>$1<space>
correspond à n'importe quel caractère suivi d'un0
. La correspondance est remplacée par le premier caractère suivi d'un espace. Cela divise la chaîne en nombres individuels.La deuxième étape
01<newline>-1
remplace0
le s avant un bloc de1
s au-
signe.La dernière étape
1+<newline>$.&
correspond à tous les blocs de1
et les remplace par la longueur du groupe.Voici un exemple avec la sortie des étapes individuelles.
la source
Vim, 56 octets
Essayez-le en ligne!
Je n'ai pas posté dans vim depuis un moment. J'utilise principalement vim parce que V est parfois une douleur. Parce que le
count
commande, qui est parfaite pour obtenir le nombre de «1» sur la ligne, écrasera tout «0» sur la ligne, donc nous ne pouvons pas le nier par la suite.Explication:
C'est un octet plus court que la méthode simple:
en raison du chaînage des commandes. Puisque celui-ci sépare les commandes, je vais l'utiliser pour l'explication.
Maintenant, chaque numéro unaire signé est sur une ligne individuelle. En utilisant '11100110001' comme exemple, à ce stade, nous aurons:
Depuis que nous avons ajouté des nouvelles lignes à la fin de chaque match, nous avions une ligne vide avant d'exécuter cela. Après avoir exécuté cela, nous aurons un «0» (car il correspondait à une série de 0 «1»). Nous appelons donc simplement
D
à supprimer cette ligne, en la laissant videla source
:%s/1+$/
vous obtiendrait un octet plus court si ce n'est pour la nécessité de faire une barre oblique inverse le+
:(-
au lieu de0
ou-0
Haskell ,
6866 octetsEssayez-le en ligne! Prend l'entrée comme une liste de zéros et de uns. Exemple d'utilisation:
f [0,0,0,1,1]
rendements[0,-2]
.Explication:
Le modèle correspondant dans
f(x:r)|(a,b)<-span(>0)r
se liex
au premier élément de l'entrée,a
à une liste (potentiellement vide) des1
s suivants etb
au reste de l'entrée. Étant donné une entrée[0,1,1,1,0,0,1]
, nous obtenonsx=0
,a=[1,1,1]
etb=[0,0,1]
.Le nombre actuel est alors soit la somme des
a
si niésx=0
, soit la somme dea
plus un six=1
. Ceci est réalisé en indexant avecx
dans une liste contenant une fonction de négation et d'incrémentation, et en appliquant la fonction résultante à la somme dea
:[(0-),(1+)]!!x$sum a
.La liste de repos
b
est soit vide, soit contient un zéro de séparation et le numéro suivant. La compréhension de la liste[z|_:t<-[b],z<-f t]
essaie de correspondreb
sur le modèle_:t
, c'est-à-dire d'oublier l'élément head et de lier le reste de la listet
. Sib
est vide, cette correspondance échoue et la compréhension de la liste est évaluée[]
, ce qui est le cas de base pour la récursivité. Sinon, la fonctionf
est récursivement appliquéet
et la compréhension de la liste est évaluée pour tous les éléments àz
partir du résultat def t
.la source
Wolfram Language (Mathematica) , 80 octets
Essayez-le en ligne!
Abuse le mécanicien de
StringCases
, car il ne vérifie pas les motifs qui se chevauchent. Puisque nous recherchons de gauche à droite, sans chevauchements, nous n'obtenons toujours que les entiers dont nous avons besoin.Explication
Ajouter un zéro à la fin
Trouvez tous les modèles suivants ...
Un seul caractère (appelez-le
x
), suivi de la plus courte longueur nulle possible ou d'une chaîne plus longue (appelez-ley
), suivi d'un zéro.Appliquer au motif correspondant: prendre la longueur de
y
. Six
est égal à zéro, annulez la valeur. Sinon, incrémentez un.Cela couvre
00
également, car cey
serait une chaîne vide, et nous calculerions-0
(== 0
).la source
Brain-Flak , 94 (70?) Octets
Essayez-le en ligne!
C'est en fait étonnamment concis pour le brain-flak.
Voici une version commentée / lisible:
Si la sortie peut être inversée, nous pouvons le faire pour 70 à la place:
Cette astuce est presque parfaite pour cette situation. Mais cela ne fonctionne pas vraiment car nous devons pousser un 0 avant de faire l'opération (en comptant les «1»), et l'opération se déroule en boucle. Le plus court que j'ai pu trouver en utilisant cette astuce est:
qui est également de 94 octets.
la source
Perl 5 , 40 + 1 (
-n
) = 41 octetsEssayez-le en ligne!
la source
Husk ,
20 18 17 1514 octetsEssayez-le en ligne!
Explication
Le fractionnement fonctionne comme ça.
ġ/
divise son argument entre chaque paire d'élémentsa,b
pour laquelle/a b
est falsifiée./a b
est une division avec des arguments inversés, doncb
divisée para
. Les valeurs pertinentes de ce programme sont les suivantes:/1 1
donne1
(véridique)./1 0
donne0
(fausse)./0 1
donneInf
(infini positif, véridique)./0 0
donneAny
(une valeur spéciale de type NaN, falsy).la source
Acc !! ,
252237 octetsUtilise
-0
. Affiche les nombres séparés par des caractères de tabulation, avec un onglet de fin. Essayez-le en ligne!Durée d'écriture de l'algorithme réel: 20 minutes. Temps de débogage de mon code de sortie décimal: 45 minutes. : ^ P
Avec commentaires
Je ne sais pas si ces commentaires expliquent très bien le code - ils sont basés sur mes notes à moi-même pendant que je l'écrivais, alors ils supposent une certaine compréhension de la façon dont Acc !! travaux. Si quelque chose a besoin de plus d'explications, faites-le moi savoir et j'essaierai de le clarifier.
la source
Python 2 ,
9692 octetsEssayez-le en ligne!
Thx à ovs et DLosc pour 2 octets chacun.
la source
R , 119 octets
Essayez-le en ligne!
Le code utilise cette solution de stackoverflow pour un problème connexe (Merci aux jaloux pour l'idée). La sortie est une chaîne séparée par des espaces imprimée sur stdout.
la source
Gelée ,
1918 octetsIl doit y avoir une meilleure façon ...
Un programme complet imprimant chaque numéro suivi d'un saut de ligne.
Essayez-le en ligne!
Comment?
la source
QBasic,
8886 octetsC'était amusant. Plusieurs révisions à partir d'une version de 107 octets ont abouti à l'un des bits les plus obscurs de QBasic que je pense avoir jamais écrit.(Edit: Curieusement, j'ai pu jouer au golf 2 octets en rendant le code plus clair.)
Remarque: ce programme lit l'utilisateur saisi un caractère à la fois sans l'écho à l'écran (résultat de l'utilisation
INPUT$(1)
au lieu de l'INPUT
instruction habituelle ). Ainsi, pendant que vous tapez, vous ne verrez pas les 1 et les 0, mais les nombres décimaux apparaîtront lorsqu'ils seront calculés. Assurez-vous de frapperEnter à la fin de l'entrée pour voir le dernier numéro et terminer le programme.Version non golfée
Explication
(AKA "Quoi ?? Cela n'a toujours aucun sens!")
La stratégie de base consiste à exécuter une boucle qui saisit un caractère à
INPUT$(1)
chaque fois, fait des trucs avec elle et continue de boucler tant que le caractère a une valeur ASCII supérieure à celle de!
(c.-à-d., Ce n'était pas une nouvelle ligne).Nous suivons les nombres en cours en utilisant deux variables.
num
est le nombre de caractères du nombre unaire signé actuel (y compris tout zéro non significatif).sign
est1
si le nombre avait un zéro0
non significatif, sinon. Ces deux doivent être initialisés à0
, ce qui est idéal pour la version golfée car les variables numériques dans QBasic sont automatiquement initialisées à0
.Chaque fois que nous lisons un caractère, la première chose à faire est de déterminer si c'est
1
ou0
. Nous utiliserons ce résultat deux fois, nous le stockons doncisZero
. Techniquement, ce nom est trompeur, car la valeur sera également vraie si le personnage est une nouvelle ligne. Notez que la vérité dans QBasic est-1
et falsey est0
.Maintenant, si nous sommes en train de lire un nombre (
num > 0
) et que nous frappons un zéro ou une fin d'entrée (isZero
), nous devons calculer le nombre que nous avons fini de lire.sign
stocke0
pour positif,1
pour négatif. Pour obtenir1
du positif et-1
du négatif, nous avons besoin1-2*sign
.num
stocke la magnitude correcte pour les positifs mais une de plus que la magnitude pour les négatifs (car elle inclut le marqueur de signe). Nous pouvons donc utilisernum-sign
pour l'ampleur.Multipliez-les ensemble et imprimez; puis réinitialiser
sign
etnum
à0
en préparation de la lecture du numéro suivant.Sinon (si nous n'avons pas atteint un zéro, ou si nous avons atteint un zéro au début d'un nombre), nous mettons à jour
sign
etnum
comme suit:sign
devient1
si nous regardons un zéro de tête; sinon, si nous en regardons un, il reste à ce qu'il était déjà. Le code golfé ests=s-z
, ce qui revient au même:z
est-1
. Depuiss
est garanti d'être0
(parce que c'est le début d'un nouveau numéro),s-z
sera1
.z
c'est0
.s-z
Reste ensuite à la valeurs
précédente.num
est incrémenté.C'est ça!
la source
JavaScript (ES6), 60 octets
Renvoie une liste d'entiers séparés par des espaces.
Cas de test
Afficher l'extrait de code
la source
Lua , 58 octets
Essayez-le en ligne!
Programme complet, prend les entrées de la ligne de commande et imprime les nombres sur stdout séparés par des retours à la ligne.
la source