Programme de chat simple


84

L'une des tâches standard les plus courantes (en particulier lors de la présentation de langages de programmation ésotériques) consiste à mettre en oeuvre un "programme cat" : lisez l'intégralité de STDIN et imprimez-le sur STDOUT. Bien que cela porte le nom de l'utilitaire de shell Unix, catil est bien sûr beaucoup moins puissant que le véritable outil utilisé pour imprimer (et concaténer) plusieurs fichiers lus à partir d'un disque.

Tâche

Vous devez écrire un programme complet qui lit le contenu du flux d’entrée standard et les écrit intégralement dans le flux de sortie standard. Si et seulement si votre langue ne prend pas en charge les flux d'entrée et / ou de sortie standard (tels qu'ils sont compris dans la plupart des langues), vous pouvez plutôt considérer ces termes comme leur équivalent le plus proche dans votre langue (par exemple, JavaScript promptet alert). Ce sont les seules formes d'entrée / sortie admissibles, car toute autre interface modifierait considérablement la nature de la tâche et rendrait les réponses beaucoup moins comparables.

La sortie doit contenir exactement l'entrée et rien d'autre . La seule exception à cette règle est la sortie constante de l'interpréteur de votre langue qui ne peut pas être supprimée, telle qu'un message d'accueil, des codes de couleur ANSI ou une indentation. Ceci s'applique également aux nouvelles lignes de fuite. Si l'entrée ne contient pas de fin de ligne, la sortie ne devrait pas en inclure non plus! (La seule exception étant que votre langue imprime toujours systématiquement une nouvelle ligne après exécution.)

La sortie vers le flux d'erreur standard est ignorée tant que le flux de sortie standard contient la sortie attendue. En particulier, cela signifie que votre programme peut s’arrêter avec une erreur lorsqu’il atteint la fin du flux (EOF), à condition que cela ne pollue pas le flux de sortie standard. Si vous faites cela, je vous encourage à ajouter une version exempte d'erreur à votre réponse également (pour référence).

Comme cela est conçu comme un défi dans chaque langue et non pas entre les langues, il existe quelques règles spécifiques à chaque langue:

  • S'il est tout à fait possible dans votre langage de distinguer les octets nuls dans le flux d'entrée standard de l'EOF, votre programme doit prendre en charge les octets nuls comme tout autre octet (en d'autres termes, ils doivent également être écrits dans le flux de sortie standard).
  • S'il est tout à fait possible dans votre langue de prendre en charge un flux d'entrée infini arbitraire (c'est-à-dire si vous pouvez commencer à imprimer des octets sur la sortie avant d'appuyer sur EOF dans l'entrée), votre programme doit fonctionner correctement dans ce cas. Par exemple, vous yes | tr -d \\n | ./my_catdevriez imprimer un flux infini de ys. C’est à vous de choisir la fréquence à laquelle vous imprimez et purgez le flux de sortie standard, mais il faut que cela se produise au bout d’un temps déterminé, quel que soit le flux (cela signifie notamment que vous ne pouvez pas attendre un caractère spécifique comme un saut de ligne avant impression).

Veuillez ajouter une note à votre réponse concernant le comportement exact en ce qui concerne les octets nuls, les flux infinis et les sorties superflues.

Règles supplémentaires

  • Il ne s'agit pas de trouver la langue avec la solution la plus courte pour cela (il y en a où le programme vide fait l'affaire) - il s'agit de trouver la solution la plus courte dans chaque langue. Par conséquent, aucune réponse ne sera marquée comme acceptée.

  • Les soumissions dans la plupart des langues seront notées en octets selon un codage préexistant approprié, généralement (mais pas nécessairement) UTF-8.

    Certaines langues, comme les dossiers , sont un peu difficiles à noter. En cas de doute, demandez s'il vous plaît sur Meta .

  • N'hésitez pas à utiliser une langue (ou une version linguistique) même si c'est plus récent que ce défi. Les langues spécifiquement écrites pour soumettre une réponse de 0 octet à ce défi sont un jeu juste mais pas particulièrement intéressant.

    Notez qu'il doit y avoir un interprète pour que la soumission puisse être testée. Il est permis (et même encouragé) d’écrire cet interprète vous-même pour une langue non encore implémentée.

    Notez également que les langues ne doivent remplir nos critères habituels pour les langages de programmation .

  • Si votre langue de choix est une variante triviale d'une autre langue (potentiellement plus populaire) qui possède déjà une réponse (pensez aux dialectes BASIC ou SQL, aux shells Unix ou aux dérivés triviaux de Brainfuck tels que Headsecks ou Unary), pensez à ajouter une note à la réponse existante: la même solution ou une solution très similaire est également la plus courte dans l’autre langue.

  • Sauf si elles ont été annulées précédemment, toutes les règles standard s'appliquent, y compris le http://meta.codegolf.stackexchange.com/q/1061 .

En passant, veuillez ne pas annuler les réponses ennuyeuses (mais valables) dans des langues où il n’ya pas grand chose à jouer au golf; ceux-ci sont toujours utiles à cette question car elle tente de compiler un catalogue aussi complet que possible. Cependant, faites principalement des réponses upvote dans les langues où l’auteur devait réellement s’efforcer de jouer au code.

Catalogue

L'extrait de pile au bas de cet article génère le catalogue à partir des réponses a) sous forme de liste des solutions les plus courtes par langue et b) sous forme de classement global.

Pour vous assurer que votre réponse apparaît, commencez votre réponse par un titre, en utilisant le modèle Markdown suivant:

## Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores en les effaçant. Par exemple:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Si vous souhaitez inclure plusieurs numéros dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou si vous souhaitez répertorier séparément les pénalités d'indicateur d'interprétation), assurez-vous que le score réel est le dernier numéro de l'en-tête:

## Perl, 43 + 2 (-p flag) = 45 bytes

Vous pouvez également faire du nom de langue un lien qui apparaîtra ensuite dans l'extrait de code:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


52
Bash, 3 octets :cat
TheDoctor

3
@TheDoctor J'imagine que cela tomberait dans la règle "n'utilisez pas de fonction intégrée qui fait exactement ce qui est nécessaire".
Paŭlo Ebermann

5
@ PaŭloEbermann Il n'y a pas de telle règle et l'échappatoire standard correspondante n'est plus acceptée. (En fait, il existe déjà une shréponse catqui contient également une solution plus courte dd.)
Martin Ender

1
Si seulement il utilisait des méthodes standard d’entrée et de sortie: ///, 0 octet .
Camarade SparklePony

1
@SparklePony Sauf que vous devez échapper aux barres obliques et barres obliques inverses.
Martin Ender

Réponses:


73

sed, 0


Le sedprogramme vide fait exactement ce qui est requis ici:

$ printf "abc\ndef" | sed ''
abc
def$ 

3
Que se passe-t-il si on écrit yes | tr -d \\n | sed ''?
BenGoldberg

@BenGoldberg Par défaut, sed fonctionne ligne par ligne. Dans ce cas, il continue donc à se glisser yesdans un tampon de signatures jusqu'à épuisement de la mémoire. Une mise en garde, je suppose ...
Digital Trauma

POSIX stipule que l'espace de modèle doit avoir une taille d'au moins 8 192 octets, IIRC. Je sais que la mise en œuvre GNU a un espace de modèle dynamique, limité uniquement par la mémoire disponible, vous êtes donc assez sûr avec celui-ci.
Toby Speight

59

Ziim , 222 201 196 185 182 octets

    ↓ ↓

 ↓ ↓     ↓
 ↗ ↗↙↔↘↖ ↖
 ↓↓⤡⤢  ⤢↙
↘ ↖⤡ ↖
  ↙
  ↕↘ ↑ ↙
→↘↖↑ ↙ ↑
→↖   ↑
→↖↘ ↙
  ↑↓↑

   ⤡

Cela ne s'affichera probablement pas correctement dans votre navigateur, voici donc un schéma du code:

entrez la description de l'image ici

Je ne peux pas penser à une structure plus simple pour résoudre le problème dans Ziim, mais je suis sûr que le code actuel est tout à fait golfable.

Ziim ne peut pas gérer des flux infinis car il est uniquement possible d'imprimer quoi que ce soit à la fin du programme.

Explication

Puisque Ziim a un modèle de flux de contrôle déclaratif plutôt unique, un algorithme pseudocode impératif ne le coupera pas ici. Au lieu de cela, j'expliquerai les bases de Ziim et présentera la structure ordonnée du code ci-dessus (d'une manière graphique similaire) en tant qu'art ASCII.

Le flux de contrôle dans Ziim se passe partout: chaque flèche qui n'est pas pointée par une autre flèche initialise un "thread" qui est traité indépendamment des autres (pas vraiment en parallèle, mais rien ne garantit dans quel ordre ils sont traités. , sauf si vous les synchronisez via une concaténation). Chacun de ces threads contient une liste de chiffres binaires, commençant par {0}. Maintenant, chaque flèche dans le code est une sorte de commande qui a une ou deux entrées et une ou deux sorties. La commande exacte dépend du nombre de flèches pointant vers quelle orientation.

Voici la liste des commandes, où m -> nindique que la commande prend des mentrées et produit des nsorties.

  • 1 -> 1, no-op : redirige simplement le fil.
  • 1 -> 1, invert : nie chaque bit du fil (et le redirige également).
  • 1 -> 1, read : remplace la valeur du thread par le prochain bit de STDIN, ou par la liste vide si nous avons atteint EOF.
  • 2 -> 1, concaténer : c’est le seul moyen de synchroniser les threads. Lorsqu'un thread atteint un côté de la flèche, il est suspendu jusqu'à ce qu'un autre thread atteigne l'autre côté. À ce stade, ils seront concaténés dans un seul thread et continueront l'exécution.
  • 2 -> 1, label : c’est le seul moyen de joindre différents chemins d’exécution. C'est simplement un no-op qui a deux entrées possibles. Ainsi, les threads entrant dans le "label" via l'une ou l'autre voie seront simplement redirigés dans la même direction.
  • 1 -> 2, split : prend un seul thread et envoie deux copies dans des directions différentes.
  • 1 -> 1, est zéro? : consomme le premier bit du fil et envoie le fil dans l’une des deux directions selon que le bit était à 0 ou à 1.
  • 1 -> 1, est vide? : consomme la liste complète (c’est-à-dire la remplace par une liste vide) et envoie le fil de discussion dans l’un des deux sens, selon que la liste était déjà vide ou non.

Donc, dans cet esprit, nous pouvons élaborer une stratégie générale. En utilisant concaténer, nous voulons ajouter à plusieurs reprises de nouveaux bits à une chaîne qui représente l’entrée entière. Nous pouvons simplement faire cela en bouclant la sortie de la concaténation dans l'une de ses entrées (et nous initialisons cela dans une liste vide, en effaçant un {0}avec isEmpty? ). La question est de savoir comment nous pouvons mettre fin à ce processus.

En plus d'ajouter le bit actuel, nous ajouterons également un 0 ou un 1 indiquant si nous avons atteint EOF. Si nous envoyons notre chaîne via isZero? , il supprimera à nouveau ce bit, mais distinguons la fin du flux, auquel cas nous laisserons simplement le thread quitter le bord de la grille (ce qui obligera Ziim à imprimer le contenu du thread sur STDOUT et à mettre fin au programme) .

Vous pouvez déterminer si vous avez atteint EOF ou non en utilisant isEmpty? sur une copie de l'entrée.

Voici le schéma que j'ai promis:

              +----------------------------+   {0} --> isEmpty --> label <--+
              |                            |                    n    |      |
              v                            |                         v      |
    {0} --> label --> read --> split --> split ------------------> concat   |
                                 |                                   |      |
                           n     v     y                             |      |
 inv --> label --> concat <-- isEmpty --> concat <-- label <-- {0}   |      |
  ^        ^          |                     |          ^             |      |
  |        |          v                     v          |             |      |
 {0}       +------- split ---> label <--- split -------+             |      |
                                 |                                   |      |
                                 +-------------> concat <------------+      |
                                                   |                        |
                                              y    v                        |
                         print and terminate <-- isZero --------------------+

Quelques notes sur par où commencer à lire:

  • Le {0}dans le coin supérieur gauche est le déclencheur initial qui lance la boucle d’entrée.
  • Le {0}coin supérieur droit est immédiatement effacé en une liste vide et représente la chaîne initiale que nous remplirons progressivement avec l'entrée.
  • Les deux autres {0}s sont introduits dans une boucle de "producteur" (une inversée, une non), pour nous fournir une offre illimitée de 0s et 1s que nous devons ajouter à la chaîne.

29
Comment pouvez-vous même écrire un programme comme celui-là sans que votre cerveau n'explose en un million de petits morceaux de tissu?
Ashwin Gupta

40

Hexagonie , 6 octets

Auparavant, il s’agissait de 3 octets (voir ci-dessous), mais cette version ne fonctionne plus depuis la dernière mise à jour de la langue. N'ayant jamais intentionnellement introduit l'erreur que cette version utilisait, j'ai décidé de ne pas la compter.


Une solution sans erreur (c'est-à-dire qui fonctionne avec l'interpréteur fixe) s'avère beaucoup plus délicate. J'ai eu du mal à l'insérer dans une grille 2x2, mais j'ai trouvé une solution maintenant, même s'il me faut les 7 octets complets :

<)@,;.(

Après dépliage, on obtient:

entrez la description de l'image ici

Etant donné que le bord initial de la mémoire est 0, le <pointeur d'instruction est dévié de manière inconditionnelle dans la diagonale Nord-Est, où il est renvoyé au chemin gris. Le .est un non-op. Maintenant, ,lit un octet, l' )incrémente de sorte que les octets valides (y compris les octets nuls) soient positifs et que EOF soit égal à 0.

Ainsi, sur EOF, l’adresse IP renvoie au chemin rouge, où se @termine le programme. Mais si nous lisons toujours un octet, l'adresse IP est renvoyée dans le chemin vert et (décrémente le bord à la valeur d'origine avant de l' ;imprimer au format STDOUT. L'adresse IP retourne maintenant inconditionnellement au chemin gris, en répétant le processus.


Après avoir écrit un script de force brute pour ma réponse à Truth Machine, je l’ai configuré pour trouver également une solution sans erreur à 6 octets pour le programme cat. Étonnamment, il en a trouvé une - oui, exactement une solution dans tous les programmes Hexagony de 6 octets possibles. Après les 50 solutions de la machine à vérité, c'était assez surprenant. Voici le code:

~/;,@~

Déploiement:

entrez la description de l'image ici

L'utilisation de ~(négation unaire) au lieu de ()est intéressante, car a) c'est un no-op sur zéro, b) il échange les côtés de la branche, c) dans certains codes, un seul ~peut être utilisé deux fois pour annuler l'opération avec lui-même . Alors voici ce qui se passe:

La première fois (chemin violet) nous traversons, ~c'est un no-op. Le /reflète l'IP dans la diagonale nord-ouest. Le chemin gris lit maintenant un caractère et multiplie son code de caractère par -1. Cela transforme l'EOF ( -1) en une valeur de vérité (positive) et tous les caractères valides en une valeur de fausseté (non positive). Dans le cas de EOF, l'IP prend le chemin rouge et le code se termine. Dans le cas d'un caractère valide, l'IP prend le chemin vert, où ~annuler la négation et ;imprimer le caractère. Répéter.


Enfin, voici la version à 3 octets qui fonctionnait dans l’interpréteur Hexagony de la version originale.

,;&

Comme dans la réponse Labyrinth, cela se termine par une erreur si le flux d'entrée est fini.

Après avoir déployé le code, il correspond à la grille hexagonale suivante:

entrez la description de l'image ici

Les .sont pas-ops. L'exécution commence sur le chemin violet.

,lit un octet, ;écrit un octet. Ensuite, l'exécution continue sur le chemin du saumon (ish?). Nous avons besoin de &pour réinitialiser le bord de la mémoire actuelle à zéro, de sorte que l’IP revienne à la ligne violette lorsqu’il atteint le coin à la fin de la deuxième ligne. Une fois que vous ,avez atteint EOF, il reviendra -1, ce qui provoquera une erreur lorsque vous ;essayez de l’imprimer.


Les diagrammes générés avec Timwi incroyable de HexagonyColorer .


2
La version à 6 octets est très très intelligente. Les brute-forceurs peuvent être incroyablement géniaux.
ETHproductions

Avez-vous un lien vers votre brute-forcer?
MD XF

@MDXF Je ne garde pas les différentes versions, mais c'est toujours une modification de ce script Ruby .
Martin Ender

36

TeaScript , 0 octet

TeaScript est un langage de golf concis compilé en JavaScript


Dans une mise à jour récente, l'entrée est implicitement ajoutée en tant que première propriété.

Essayez-le en ligne


Alternativement, 1 octet

x

xcontient l'entrée dans TeaScript. La sortie est implicite


J'étais sur le point de poster ceci :)
Kritixi Lithos

5
Hah, je pensais que "Alternativement" était un nom de langue ...
Quelklef

28

Brian & Chuck , 44 octets

#{<{,+?+}_+{-?>}<?
_}>?>+<<<{>?_}>>.<+<+{<{?

J'ai initialement créé ce langage pour Créer un langage de programmation qui semble seulement être inutilisable . Il s’avère être un très bon exercice pour résoudre des problèmes simples.

L'essentiel: Chacune des deux lignes définit un programme de type Brainfuck qui fonctionne sur le code source de l'autre programme - le premier programme s'appelle Brian et le second s'appelle Chuck. Seul Brian sait lire et seul Chuck peut écrire. Au lieu des boucles de Brainfuck, vous passez le ?contrôle à l'autre programme (et les rôles de pointeur d'instruction et de tête de bande changent également). Un ajout à Brainfuck est {et }qui scanne la bande pour la première cellule différente de zéro (ou l'extrémité gauche). Aussi, _sont remplacés par des octets nuls.

Bien que je ne pense pas que ce soit encore optimal, je suis plutôt satisfait de cette solution. Ma première tentative a été de 84 octets et, après plusieurs sessions de golf avec Sp3000 (et s’inspirant de ses tentatives), j’ai réussi à le réduire lentement à 44, quelques octets à la fois. +}+Son idée était particulièrement brillante (voir ci-dessous).

Explication

Les entrées sont lues dans la première cellule de la bande de Chuck, puis copiées minutieusement à la fin de la bande de Brian, où elles sont imprimées. En le copiant à la fin, nous pouvons économiser des octets en réglant le caractère précédent à zéro.

Il ne #s'agit que d'un espace réservé, car le contrôle de commutation n'exécute pas la cellule activée. {<{assure que la tête de la bande se trouve sur la première cellule de Chuck. ,lit un octet de STDIN ou -1si nous appuyons sur EOF. Donc, nous incrémentons cela avec +pour le rendre nul pour EOF et non nul pour le reste.

Supposons pour l'instant que nous ne sommes pas encore à EOF. Donc, la cellule est positive et ?passera le contrôle à Chuck. }>déplace la tête de la bande (sur Brian) vers +le _et ?remet le contrôle à Brian.

{-décrémente maintenant la première cellule de Chuck. Si ce n'est pas encore zéro, nous passons à nouveau le contrôle à Chuck avec ?. Cette fois, }>la tête de la bande passe sur deux cellules de Brian situées à droite de la dernière cellule non nulle. Au départ c'est ici:

#{<{,+?+}_+{-?>}<?__
                   ^

Mais plus tard, nous aurons déjà quelques personnages là-bas. Par exemple, si nous avons déjà lu et imprimé abc, cela ressemblerait à ceci:

#{<{,+?+}_+{-?>}<?11a11b11c__
                            ^

Où les 1s sont en fait de 1 octet (nous verrons plus tard de quoi il en retourne).

Cette cellule sera toujours égale à zéro, cette fois- ? ci ne changera pas de contrôle. >déplace encore une autre cellule vers la droite et +incrémente cette cellule. C'est pourquoi le premier caractère de l'entrée se termine par trois cellules à droite de la ?(et chacune des trois cellules suivantes plus à droite).

<<<revient au dernier caractère de cette liste (ou ?si c'est le premier caractère), et {>revient à la +bande de Brian pour répéter la boucle, ce qui transfère lentement la cellule d'entrée à la fin de la bande de Brian.

Une fois que cette cellule d’entrée est vide, l’ ?après {-ne changera plus de contrôle. Ensuite, >}<déplacez la tête de bande de Chuck sur les _commutateurs et, de sorte que la seconde moitié de Chuck soit exécutée à la place.

}>>passe à la cellule que nous avons maintenant écrite après la fin de la bande de Brian, l'octet que nous avons lu dans STDIN, nous le réimprimons .. Pour }pouvoir dépasser ce nouveau caractère sur la bande, nous devons combler l'écart de deux octets nuls. Nous les incrémentons donc 1avec <+<+(c'est pourquoi il y a un octet entre les caractères réels sur la bande finale). {<{Revient enfin au début de la bande de Brian et ?commence tout depuis le début.

Vous pourriez vous demander ce qui se passe si le caractère que nous avons lu était un octet nul. Dans ce cas, la cellule nouvellement écrite serait elle-même zéro, mais comme elle se trouve à la fin de la bande de Brian et que nous ne nous soucions pas de savoir où se trouve cette fin, nous pouvons simplement ignorer cela. Cela signifie que si l'entrée était ab\0de, la bande de Brian ressemblerait à ceci:

#{<{,+?+}_+{-?>}<?11a11b1111d11e

Enfin, une fois que nous aurons vu EOF, la première chose ?sur la bande de Brian sera un non-op. À ce stade, nous terminons le programme. La solution naïve serait de passer à la fin du contrôle de la bande de Chuck et le commutateur, de sorte que le programme termiantes: >}>}<?. C’est là que l’idée vraiment intelligente de Sp3000 permet d’économiser trois octets:

+transforme la première cellule de Chuck en 1. Cela signifie }qu'un point de départ et se trouve _au milieu de la bande de Chuck. Au lieu de sauter passé, nous simplement combler l'écart en le transformant en un 1avec +aussi bien. Voyons maintenant ce que le reste du code de Brian fait avec ce Chuck modifié ...

{retourne à la première cellule de Chuck, comme d'habitude, et la -transforme en octet nul. Cela signifie que ?c'est un non-op. Mais maintenant >}<, qui place généralement la tête de la bande au milieu de la bande de Chuck, passe au-delà de celle-ci jusqu'à la fin de la bande de Chuck, ?puis passe le contrôle à Chuck, mettant fin au code. C'est bien quand les choses s'arrangent ... :)


25

Haskell, 16 octets

main=interact id

interactlit l'entrée, la passe à la fonction donnée en tant qu'argument et affiche le résultat reçu. idest la fonction identité, c’est-à-dire qu’elle renvoie son entrée sous forme inchangée. Merci à la paresse de Haskell interactpeut travailler avec une entrée infinie.


23

sh + binutils, 3 2 octets

dd

Eh bien, pas aussi évident. De @ Random832

Original:

cat

La douloureusement évidente ...: D


12
Je ferai un meilleur: dd.
Random832

J'allais faire chat ... D:
ev3commander

1
Oui, c’est génial et tout ... sauf 170 reps pour taper cat???
MD XF

1
@ MDXF qu'en est-il qui sait combien de représentants d'un segfault? ;)
caird coinheringaahing

23

Fonction , 16 octets

╔═╗
╚╤╝

(Codé en UTF-16 avec une nomenclature)

Explication

La boîte retourne le contenu de STDIN. L'extrémité lâche le sort.


19

Motorola MC14500B Code de la machine , 1.5 bytes

Écrit en hexadécimal:

18F

Écrit en binaire:

0001 1000 1111

Explication

1   Read from I/O pin
8   Output to I/O pin
F   Loop back to start

Les opcodes sont de 4 bits chacun.


1
-1 pas de capture d'écran, exemple ou lien Essayez-le en ligne: P (jk)
MD XF

2
+1 La seule façon dont je puisse penser à l'optimiser serait de souder simplement la broche d'entrée à la broche de sortie et de retirer la puce de son support: P
Wossname

16

Croissant Mornington , 41 octets

Take Northern Line to Mornington Crescent

Je ne sais pas du tout si Mornington Crescent peut gérer des octets nuls et toutes les entrées sont lues avant le démarrage du programme, car c'est la nature du langage.


15

Brainfuck, 5 octets

,[.,]

Équivalent au pseudocode:

x = getchar()
while x != EOF:
    putchar(x)
    x = getchar()

Cela gère des flux infinis, mais traite les octets nuls comme EOF. Le fait que BF puisse ou non gérer correctement les octets nuls varie d'une mise en œuvre à l'autre, mais cela suppose l'approche la plus courante.


1
ZUT! Vous m'avez battu à 5 minutes!
Kirbyfan64sos

Si le premier caractère est NULL, cela ne fonctionnera pas correctement. Donc ça devrait être +[,.]vrai?
Shelvacu

6
@Shel Ceci utilise 0x00 comme octet EOF. Si le premier caractère est EOF, il n’imprimera rien et fonctionnera comme prévu.
Mego

2
"pseudocode" oh allez, c'est clairement juste sans crochets, sans point-virgule C: P
MD XF

14

Labyrinthe , 2 octets

,.

Si le flux est fini, cela se terminera par une erreur, mais toute la sortie produite par l'erreur ira à STDERR, le flux de sortie standard est donc correct.

Comme dans Brainfuck, ,un octet est lu (en le poussant sur la pile principale de Labyrinth) et .écrit un octet (extrait de la pile principale de Labyrinth).

La raison de ce que les deux boucles est ,et .sont « morts » dans les extrémités (très trivial) labyrinthe représenté par le code source, de telle sorte que le pointeur d'instruction tourne simplement autour de l'endroit et se déplace vers l'autre commande.

Lorsque nous frappons, EOF ,pousse à la -1place et .génère une erreur car ce -1n'est pas un code de caractère valide. Cela pourrait effectivement changer à l'avenir, mais je ne l'ai pas encore décidé.


Pour référence, nous pouvons résoudre ceci sans erreur dans 6 octets comme suit

,)@
.(

Ici, les )octets incrémentés sont lus, ce qui donne 0à EOF et quelque chose de positif sinon. Si la valeur est 0, l'adresse IP continue, en appuyant sur le bouton @qui termine le programme. Si la valeur était positive, l'IP se tournera plutôt à droite vers ce (qui décrémente le haut de la pile à sa valeur d'origine. L'adresse IP est maintenant dans un coin et continuera simplement à faire des virages à droite, imprimant avec ., lisant un nouvel octet avec ., avant qu'il ne touche la fourche )immédiatement.


13

C, 40 octets

main(i){while(i=~getchar())putchar(~i);}

main () {while (255-putchar (getchar ()));} est un couple d'octets plus court.
Alchymist

1
Malheureusement, cela se termine prématurément sur les octets 0xFF et ajoute un octet 0xFF à l'entrée s'il ne le contient pas.
Dennis

Qu'en est-il des 36 octets suivants: main () {pour (;; putchar (getchar ()));};
Johan du Toit

@ user2943932 Lorsqu'il atteint EOF, getcharrenvoie -1 , afin que votre code imprime un flux infini d'octets 0xFF après l'entrée (finie).
Dennis

12

> <> , 7 octets

i:0(?;o

Essayez-le ici . Explication:

i:0(?;o
i        Take a character from input, pushing -1 if the input is empty
 :0(     Check if the input is less than 0, pushing 1 if true, 0 if false
    ?;   Pop a value of the top of the stack, ending the program if the value is non-zero
      o  Otherwise, output then loop around to the left and repeat

Si vous voulez qu'il continue jusqu'à ce que vous lui donniez plus d'informations, remplacez-le ;par !.


Oh, mec, j'espérais publier la> <> réponse ...: P (+1!)
El'endia Starman

1
io(2 octets) fait de même, mais plante et écrit something smells fishy...dans STDERR à la fin de l'exécution, ce qui est autorisé.
Lynn

@Mauris l'interpréteur en ligne ne génère que des octets nuls au lieu de se terminer par une erreur.
DanTheMan

11

Assemblage X86, 70 octets

Démontage avec objdump:

00000000 <.data>:
   0:   66 83 ec 01             sub    sp,0x1
   4:   66 b8 03 00             mov    ax,0x3
   8:   00 00                   add    BYTE PTR [eax],al
   a:   66 31 db                xor    bx,bx
   d:   66 67 8d 4c 24          lea    cx,[si+0x24]
  12:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  15:   01 00                   add    DWORD PTR [eax],eax
  17:   00 00                   add    BYTE PTR [eax],al
  19:   cd 80                   int    0x80
  1b:   66 48                   dec    ax
  1d:   78 1c                   js     0x3b
  1f:   66 b8 04 00             mov    ax,0x4
  23:   00 00                   add    BYTE PTR [eax],al
  25:   66 bb 01 00             mov    bx,0x1
  29:   00 00                   add    BYTE PTR [eax],al
  2b:   66 67 8d 4c 24          lea    cx,[si+0x24]
  30:   ff 66 ba                jmp    DWORD PTR [esi-0x46]
  33:   01 00                   add    DWORD PTR [eax],eax
  35:   00 00                   add    BYTE PTR [eax],al
  37:   cd 80                   int    0x80
  39:   eb c9                   jmp    0x4
  3b:   66 b8 01 00             mov    ax,0x1
  3f:   00 00                   add    BYTE PTR [eax],al
  41:   66 31 db                xor    bx,bx
  44:   cd 80                   int    0x80

La source:

sub esp, 1
t:
mov eax,3
xor ebx,ebx
lea ecx,[esp-1]
mov edx,1
int 0x80
dec eax
js e
mov eax,4
mov ebx,1
lea ecx,[esp-1]
mov edx,1
int 0x80
jmp t
e:
mov eax,1
xor ebx,ebx
int 0x80

1
Donc, objdumpdésassemblez-le en code 32 bits, alors que vous semblez avoir compilé en 16 bits. Quoi croire? Depuis que vous utilisez int 0x80, je suppose que cela est destiné à Linux, mais pourquoi compiler en 16 bits alors?
Ruslan

@Ruslan Je ne savais même pas qu'il avait été compilé en 16 bits ...
kirbyfan64sos

11

Universal Lambda , 1 octet

!

Un programme Universal Lambda est un codage d'un terme lambda en binaire, découpé en morceaux de 8 bits, remplissant des morceaux incomplets avec des bits quelconques , convertis en flux d'octets.

Les bits sont traduits en un terme lambda comme suit:

  • 00 introduit une abstraction lambda.
  • 01 représente une application de deux termes ultérieurs.
  • 111..10, Avec n répétitions du bit 1, se réfère à la variable de la n ième parent lambda; c'est-à-dire qu'il s'agit d'un index de De Bruijn en unaire.

Par cette conversion, 0010est la fonction identité λa.a, ce qui signifie que tout programme à octet unique de la fiche 0010xxxxest un catprogramme.


1
Mais !est 0x21-ce pas 0x4_?
wchargin

Fixé. --------
Lynn

10

PowerShell, 88 41 30 octets

$input;write-host(read-host)-n

EDIT - j'ai oublié que je peux utiliser la $inputvariable automatique pour l'entrée de pipeline ... EDIT2 - pas besoin de vérifier l'existence de$input

Ouais, alors ... STDIN dans PowerShell est ... bizarre, devrions-nous dire. En partant du principe que nous devons accepter les contributions de tous les types de STDIN, c’est une des réponses possibles à ce catalogue, et je suis sûr qu’il en existe d’autres. 1

La saisie de pipeline dans PowerShell ne fonctionne toutefois pas comme vous le pensez. Étant donné que la tuyauterie dans PowerShell est une fonction du langage et non de l'environnement / du shell (et que PowerShell n'est pas vraiment uniquement un langage de toute façon), il existe des problèmes de comportement.

Pour commencer, et le plus pertinent pour cette entrée, le tuyau n'est pas évalué instantanément (la plupart du temps). Ce qui signifie, si nous avons command1 | command2 | command3dans notre coquille, command2ne prendra pas entrée ou commencer le traitement jusqu'à ce que , command1battant ... à moins que vous encapsulez votre command1avec ForEach-Object... ce qui est différent de ForEach. (Même si ForEachc'est un alias pour ForEach-Object, mais c'est une question distincte, puisque je parle en ForEachtant que déclaration, pas d'alias)

Cela signifierait que quelque chose comme yes | .\simple-cat-program.ps1(même si yesn'existe pas vraiment, mais quoi que ce soit) ne fonctionnerait pas car yesne serait jamais complète. Si nous pouvions le faire, ForEach-Object -InputObject(yes) | .\simple-cat-program.ps1cela devrait (en théorie) fonctionner.

Apprendre à connaître ForEach et ForEach-Object sur Microsoft "Hé, le scripteur!" Blog.

Ainsi, tous ces paragraphes expliquent pourquoi if($input){$input}existe. Nous prenons un paramètre d'entrée spécialement créé automatiquement si une entrée de pipeline est présente, testons s'il existe et si c'est le cas, le générons.

Ensuite, nous prenons les entrées de l'utilisateur (read-host)via ce qui est essentiellement un flux STDIN séparé, et write-hostle retour en arrière, avec l' -nindicateur (en abrégé -NoNewLine). Notez que cela ne prend pas en charge les entrées de longueur arbitraire, car read-hostelles ne se termineront que lorsqu'un saut de ligne est entré (techniquement lorsque l'utilisateur appuie sur "Entrée", mais fonctionnellement équivalent).

Phew.

1 Mais il existe d'autres options:

Par exemple, si nous nous intéressions uniquement aux intrants dans les pipelines et si nous n’exigeions pas un programme complet, vous pourriez faire quelque chose comme | $_ce qui produirait simplement l’intrant. (En général, c'est quelque peu redondant, car PowerShell génère une sortie implicite de choses "laissées derrière" après les calculs, mais c'est un aparté.)

Si nous ne nous préoccupons que de la saisie interactive des utilisateurs, nous pourrions simplement l'utiliser write-host(read-host)-n.

En outre, cette fonction a la bizarrerie caractéristique d'accepter l' entrée de ligne de commande, par exemple .\simple-cat-program.ps1 "test"ne remplir (et de sortie) de la $avariable.


N'oubliez pas vos alias intégrés!
Chad Baxter

10

Cubix , 6 5 octets

Gère maintenant les octets nuls!

@_i?o

Cubix est un esolang bidimensionnel basé sur une pile. Cubix est différent des autres langages 2D en ce que le code source est encapsulé à l’extérieur d’un cube.

Testez-le en ligne! Remarque: il y a un délai de 50 ms entre les itérations.

Explication

La première chose à faire par l’interprète consiste à déterminer le plus petit cube sur lequel le code s’intégrera. Dans ce cas, la longueur du bord est 1. Ensuite, le code est .rempli avec no-ops jusqu'à ce que les six côtés soient remplis. Les espaces sont supprimés avant le traitement, ce code est donc identique à celui ci-dessus:

  @
_ i ? o
  .

Maintenant, le code est exécuté. L'IP (pointeur d'instruction) commence sur la face gauche extrême, en direction est.

Le premier caractère rencontré par l'adresse IP _est un miroir qui inverse l'adresse IP si elle fait face au nord ou au sud; il fait actuellement face à l'est, donc cela ne fait rien. Suivant est i, qui entre un octet de STDIN. ?tourne l'IP à gauche si l'élément du haut est négatif, ou à droite s'il est positif. Il y a trois chemins possibles ici:

  • Si l'octet entré est -1 (EOF), l'IP tourne à gauche et frappe @, ce qui termine le programme.
  • Si l'octet entré est 0 (octet nul), l'IP continue simplement, en sortant l'octet avec o.
  • Sinon, l'IP tourne à droite, traverse la face inférieure et frappe le miroir _. Cela le retourne et le renvoie au ?, ce qui le retourne à droite et renvoie l'octet.

Je pense que ce programme est optimal. Avant que Cubix puisse gérer des octets nuls (EOF était égal à 0, pas -1), ce programme fonctionnait pour tout sauf les octets nuls:

.i!@o

J'ai écrit un gros mot pour trouver tous les programmes de chat de 5 octets. Bien que cela prenne environ 5 minutes, la dernière version a trouvé 5 programmes:

@_i?o   (works as expected)
@i?o_   (works in exactly the same way as the above)
iW?@o   (works as expected)
?i^o@   (false positive; prints U+FFFF forever on empty input)
?iWo@   (works as expected)

Veuillez ne pas éditer une douzaine de messages à la fois. Vous êtes en train d'inonder la première page. 3 à la fois n'est pas un problème, mais si vous devez faire plus que cela alors s'il vous plaît faites vos modifications en petits lots toutes les 12 heures environ.
Martin Ender

@MartinEnder Désolé, je viens de remarquer cela. Je les espacerai dans le futur.
ETHproductions

9

Vitsy, 2 octets

zZ

zrécupère toute la pile d’entrée et le place dans la pile de programmes active. Zaffiche toute la pile active sur STDOUT.

Méthode alternative:

Je \ il \ o
Répétez le caractère suivant pour la longueur de la pile d’entrée.
  i Prenez un élément de l’entrée.
   l \ Répétez le caractère suivant pour la longueur de la pile de programmes active.
     O Affiche le premier élément de la pile sous forme de caractère.

2
^ _ ^ Ayez un +1 quand même! :)
El'endia Starman

Les votes de pitié, mon préféré!
Addison Crump

Pourquoi les votes négatifs? Cela semble être une entrée parfaitement valide
Conor O'Brien

1
Il est valable selon toutes les spécifications.
Addison Crump

9

MarioLANG , 11 octets

,<
."
>!
=#

Je ne suis pas tout à fait sûr que ce soit optimal, mais c'est le plus court que j'ai trouvé.

Ceci prend en charge des flux infinis et se termine par une erreur lorsque EOF est atteint (du moins, l'implémentation de référence Ruby le permet).

Il existe une autre version de celui-ci qui transforme Mario en un ninja qui peut faire un double saut:

,<
.^
>^
==

Dans les deux cas, Mario commence à tomber dans la colonne de gauche, où ,un octet est lu et un octet .écrit (ce qui génère une erreur à EOF car ,il ne renvoie pas de caractère valide). >s’assure que Mario marche à droite ( =c’est juste un terrain sur lequel il peut marcher). Ensuite, il monte, soit par un double saut avec, ^soit par un ascenseur (la paire "et #) avant que celui-ci <lui dise de revenir à la colonne de gauche.


8

rs , 0 octet


Sérieusement. rs ne fait qu'imprimer ce qu'il obtient si le script donné est complètement vide.


7

GolfScript, 3 octets

:n;

Le programme vide fait écho à l'entrée standard. La langue ne peut éventuellement pas gérer des flux infinis. Cependant, il ajoute une nouvelle ligne, comme l'a mentionné @Dennis. Pour ce faire, il encapsule toute la pile dans un tableau et appelle puts, qui est défini comme print n print, où nest un retour à la ligne. Cependant, nous pouvons redéfinir nSTDIN, puis vider la pile, ce qui est précisément le :n;cas.


7

Voiture à moitié cassée dans une circulation dense , 9 + 3 = 12 octets

#<
o^<
 v

La voiture à moitié brisée dans un trafic intense (HBCHT) prend les entrées comme argument de ligne de commande, alors exécutez comme

py -3 hbcht cat.hbc -s "candy corn"

Notez que le +3 est pour le -sdrapeau, qui sort en tant que caractères. De plus, HBCHT ne semble pas gérer les NUL, car tous les zéros sont supprimés de la sortie (par exemple, la 97 0 98sortie est composée de deux caractères ab).

Explication

Dans HBCHT, votre voiture commence à la oet votre objectif est la sortie #. ^>v<diriger le mouvement de la voiture tout en modifiant simultanément une bande de type BF ( ^>v<traduire en +>-<). Cependant, comme le suggère le nom de la langue, votre voiture ne peut virer à droite. Toute tentative de virage à gauche est complètement ignorée (y compris ses effets sur la mémoire). Notez que ceci est uniquement destiné aux virages - votre voiture est parfaitement capable de rouler en avant / en arrière.

D'autres aspects intéressants à propos de HBCHT sont que la direction initiale de votre voiture est aléatoire et que la grille est toroïdale. Ainsi, nous avons juste besoin de la voiture pour arriver à la sortie sans modifier la bande pour les quatre directions initiales:

  • Le haut et le bas sont simples, menant directement à la sortie.

  • Pour la gauche, nous enveloppons et exécutons <et incrémentons avec ^. Nous ne pouvons pas tourner à gauche au prochain <, nous encapsulons et décrémentons v, en annulant l’incrément précédent. Puisque nous nous dirigeons vers le bas, nous pouvons tourner à droite à la fin <et quitter, après avoir déplacé le pointeur deux fois et ne modifier aucune valeur de cellule.

  • Pour la droite, nous faisons la même chose que la gauche mais sautons la première ^puisque nous ne pouvons pas tourner à gauche.


Edit : il se trouve que l’interpréteur HBCHT ne vous permet d’exécuter qu’un seul chemin via un indicateur de ligne de commande, par exemple

py -3 hbcht -d left cat.hbc

Toutefois, non seulement le drapeau est trop coûteux pour cette question particulière (au moins 5 octets pour " -d u"), mais il semble que tous les chemins doivent encore pouvoir se rendre à la sortie pour que le code soit exécuté.


7

Minkolang , 5 octets

od?.O

Essayez ici.

Explication

olit un caractère depuis l'entrée et insère son code ASCII dans la pile ( 0si l'entrée est vide). dduplique ensuite le haut de la pile (le caractère qui vient d'être lu). ?est un trampoline conditionnel, qui saute l'instruction suivante du haut de la pile n'est pas 0. Si l'entrée était vide, alors le .n'est pas sauté et le programme s'arrête. Sinon, Oaffiche le haut de la pile sous forme de caractère. La nature toroïdale de Minkolang signifie que cela se répète au début.


2
Grar! Tu as battu ma langue! INACCEPTABLE! +1
Addison Crump

7

INTERCALL , 133 octets

wat

INTERCALL IS A ANTIGOLFING LANGUAGE
SO THIS HEADER IS HERE TO PREVENT GOLFING IN INTERCALL
THE PROGRAM STARTS HERE:
READ
PRINT
GOTO I

On dirait que quelqu'un a vraiment joué au golf dans un langage purement anti-golf ... 133-116 = 17
Erik the Outgolfer

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Puisque le programme cat est assez simple, ce n'est pas le cas de tous les programmes ... codegolf.stackexchange.com/a/82748/53745
TuxCrafting

La personne qui a créé la langue avait l’intention d’utiliser des chiffres romains, mais si c’était le cas d’imprimer 500(pas sûr), ce le serait PRINT D, non? (à l'exclusion de l'entête)
Erik the Outgolfer

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Non, INTERCALL ne peut imprimer que des caractères ASCII et utiliser une pile. Ainsi, par exemple, pour imprimer le caractère avec la valeur ascii 20, le code est PUSH XX<newline>PRINTou PUSH XX AND PRINT. Oh et je suis le créateur d'INTERCALL
TuxCrafting le

7

V , 0 octet

Essayez-le en ligne!

L'idée de "mémoire" de V n'est qu'un gigantesque tableau 2D de caractères. Avant qu'un programme ne soit exécuté, toutes les entrées sont chargées dans ce tableau (appelé "The Buffer"). Ensuite, à la fin de tout programme, tout le texte du tampon est imprimé.

En d'autres termes, le programme vide est un programme cat.


6

Bonhomme de neige 1.0.2 , 15 caractères

(:vGsP10wRsp;bD

Tiré directement du examplesrépertoire de Snowman . Lit une ligne, imprime une ligne, lit une ligne, imprime une ligne ...

Notez qu'en raison d'un détail d'implémentation, lorsque STDIN est vide, vgla même chose sera renvoyée comme pour une ligne vide. Par conséquent, cela imprimera de manière répétée les nouvelles lignes dans une boucle infinie une fois que STDIN est fermé. Cela peut être corrigé dans une future version.

Explication du code:

(        // set two variables (a and f) to active—this is all we need
:...;bD  // a "do-loop" which continues looping as long as its "return value"
         // is truthy
  vGsP   // read a line, print the line
  10wRsp // print a newline—"print" is called in nonconsuming mode; therefore,
         // that same newline will actually end up being the "return value" from
         // the do-loop, causing it to loop infinitely


5

Fission , 4 octets

R?J!

N'est-ce pas agréable de battre les exemples de programmes dans le référentiel de la langue? :) Pour référence, il a la solution de 7 octets

R?J0;0!

Explication

Alors, Rcommence le flux de contrôle avec un atome allant vers la droite. ?lit un caractère de STDIN dans la masse de l'atome. Tant que nous lisons des caractères, l’énergie reste égale à zéro. L’ Jemperon n’est donc pas opérant et !imprime le caractère. L'atome fait une boucle au début ( Rest désormais un no-op) et répète l'ensemble du processus.

Lorsque nous appuierons sur EOF, ?l'énergie de l'atome sera définie sur 1, de sorte que l' Jmpd ignorera maintenant la commande d'impression. Mais lorsqu'un atome frappe ? après que EOF a déjà été renvoyé, il sera détruit à la place, ce qui terminera le programme.

(La solution de l'auteur du langage utilise un explicite ;pour terminer le programme, qui est ignoré avec deux 0portails sinon.)


5

Shtriped , 20 octets

e )
"
 r )
 s )
 "
"

Cela démontre de manière effrontée que presque toute chaîne ASCII imprimable est un identifiant valide dans Shtriped.

Comment ça fonctionne:

e )   \ declares a variable named )
"     \ defines a function with 0 arguments named "
 r )  \ gets a line of string input, saving it to )
 s )  \ prints ) as a string
 "    \ recursively calls ", effectively looping forever
"     \ calls " from the main scope to get things started

Il n'y a pas de véritable moyen de détecter EOF, donc cela boucle pour toujours comme la réponse Python .

Vous pouvez facilement le faire arrêter lorsqu'une ligne vide est donnée (30 octets):

e )
"
 r )
 d ) \ tries to decrement ), if it was the empty string, aka 0, it can't, so 0 is returned all the way up
 i ) \ increment ) to put it back to normal after possibly decrementing
 s )
 "
"

Notez que les E / S Shtriped ne prennent en charge que l’ ASCII imprimable , les onglets, les sauts de ligne, les retours à la ligne, les onglets verticaux et les sauts de formulaire (100 caractères au total). En effet, en interne, les chaînes sont représentées sous forme d'entiers à précision arbitraire non négative et il doit exister un alphabet fini de caractères pour pouvoir encoder toutes les chaînes.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.