Mise à jour des fichiers de langue de Minecraft

11

Dans la version 1.13, les fichiers de langue Minecraft sont passés d'un simple format multi-lignes clé = valeur à JSON .

Défi

Écrivez un programme convertissant du format d'origine en renvoyant une chaîne JSON. L'entrée peut être prise en utilisant n'importe quelle méthode d'entrée standard, la sortie doit être json à partir de n'importe quelle méthode de sortie standard

Le format d'origine contient des lignes avec des paires clé = valeur, par exemple

tile.dirt.name=Dirt
advMode.nearestPlayer=Use "@p" to target nearest player

build.tooHigh=Height limit for building is %s blocks

Doit être converti en un grand objet JSON avec clé = valeur

{
    "tile.dirt.name": "Dirt",
    "advMode.nearestPlayer": "Use \"@p\" to target nearest player",
    "build.tooHigh": "Height limit for building is %s blocks"
}

Quelques détails

  • Tout JSON valide est autorisé tant qu'il ne contient que les bonnes paires clé / valeur. Les virgules de fin sont autorisées car Minecraft les autorise.
  • Les seules choses à échapper sont les guillemets. (Aucune nouvelle ligne, barre oblique inverse ou autre élément brisant json n'existait dans le fichier de langue avant la version 1.13)
  • Les lignes vides doivent être ignorées
  • Les lignes contiennent exactement un égal

Cas de test

Contribution:

tile.dirt.name=Dirt
advMode.nearestPlayer=Use "@p" to target nearest player

build.tooHigh=Height limit for building is %s blocks

Production:

{
    "tile.dirt.name": "Dirt",
    "advMode.nearestPlayer": "Use \"@p\" to target nearest player",
    "build.tooHigh": "Height limit for building is %s blocks"
}

Contribution:

translation.test.none=Hello, world!
translation.test.complex=Prefix, %s%2$s again %s and %1$s lastly %s and also %1$s again!
translation.test.escape=%%s %%%s %%%%s %%%%%s
translation.test.invalid=hi %
translation.test.invalid2=hi %  s
translation.test.args=%s %s
translation.test.world=world

Production:

{
  "translation.test.none": "Hello, world!",
  "translation.test.complex": "Prefix, %s%2$s again %s and %1$s lastly %s and also %1$s again!",
  "translation.test.escape": "%%s %%%s %%%%s %%%%%s",
  "translation.test.invalid": "hi %",
  "translation.test.invalid2": "hi %  s",
  "translation.test.args": "%s %s",
  "translation.test.world": "world",
}

Contribution:

stat.mineBlock=%1$s Mined
stat.craftItem=%1$s Crafted
stat.useItem=%1$s Used
stat.breakItem=%1$s Depleted

Production:

{
    "stat.mineBlock": "%1$s Mined",
    "stat.craftItem": "%1$s Crafted",
    "stat.useItem": "%1$s Used",
    "stat.breakItem": "%1$s Depleted"
}
pfg
la source
1
Comment tile.dirt.namedevient-il "block.minecraft.dirt"?
Pavel
@ Pavel uuh ... whoops. Correction de ça. C'était involontaire
pfg
5
Est-il garanti que chaque ligne non vide contient exactement 1 =?
user202729
@ user202729 yes
pfg
3
Je serais prêt à parier que vous avez réellement besoin d'une solution à ce problème et que vous avez l'intention d'en utiliser une pour convertir vos fichiers. :)
mbomb007

Réponses:

4

Python 3, 91 77 octets

-14 octets grâce à OMᗺ

Je pensais que l'impression d'un dictionnaire Python serait assez proche de JSON pour en faire un langage très compétitif pour ce défi. Cependant, la représentation sous forme de chaîne des dictionnaires python est suffisamment différente de JSON pour que j'aie plus de chance d'utiliser la bibliothèque JSON intégrée de python. Je parie que cela peut être fait plus succinctement en JavaScript.

import json
f=lambda x:json.dumps(dict(i.split("=")for i in x.split("\n")if i))

Essayez-le en ligne!


Éditer:

Bash + Sed, 68 63 octets

Correction d'un bug grâce à OMᗺ et Night 2
-5 Bytes grâce à OMᗺ

J'ai réalisé qu'il pourrait être plus efficace d'octet de convertir directement le texte en JSON sans le regrouper dans un objet, comme ce fut mon approche pour la solution python. Par octet, sed est le langage le plus puissant pour le remplacement de regex que je connaisse.

echo {`echo "$1"|sed 's/"/\\\"/g;s/\(.*\)=\(.*\)/"\1":"\2",/'`}

Essayez-le en ligne!

Explication

echo {`                                  #  prints the leading curly brace
       echo "$1"|sed                     # feeds the input into sed
       's/"/\\"/g;                       # replaces " with \"
       s/\(.*\)=\(.*\)/"\1":"\2",/'      # surrounds the left and right hand sides of the equals with quotes and joins them with a colon
`}                                       # prints the closing curly brace
Coton Zachary
la source
8
Si vous répondez dans deux langues différentes, n'hésitez pas à publier cela en deux réponses distinctes.
mbomb007
Pour la réponse bash + sed, essayez d'utiliser l' -rindicateur pour sed (+3 octets) afin de ne pas avoir besoin d'échapper aux groupes de capture (-4 octets) tio.run/##LYq7CgIxEEX7/…
user41805
4

Vim, 44 octets

O{<Esc>:%s/"/\\"/g|%s/\v(.*)\=(.*)/"\1":"\2",
o}

Explication:

O{<Esc>                                           Prepend {
       :%s/"/\\"/g                                Escape all "
                  |%s/\v(.*)\=(.*)/"\1":"\2",     Json-ify lines
o}                                                Append }
oktupol
la source
3

Rouille , 150 octets

|s:String|s.replace('"',"\\\"").split('\n').filter(|l|l.len()>0).map(|l|format!("\"")+&l.replace('=',"\":\"")+"\",").fold(format!("{{"),|r,n|r+&n)+"}"

Essayez-le en ligne!

Est-il plus long que Java?

Herman L
la source
2

Retina 0.8.2 , 35 octets

"
\"
=
": "
G`.
.+
    "$&",
^
{¶
$
¶}

Essayez-le en ligne! Serait de 34 octets dans Retina 1 que vous pouvez utiliser L$`.+au lieu de G`.et .+. Explication:

"
\"

Échappez aux citations.

=
": "

Corrigez le séparateur clé / valeur. (Si la valeur peut contenir un =, utilisez 1`=au coût de 2 octets.)

G`.

Supprimez les lignes vides.

.+
    "$&",

Mettez chaque ligne entre guillemets. (Les guillemets intérieurs ont été ajoutés plus tôt.)

^
{¶
$
¶}

Envelopper la sortie entière dans {}s.

Neil
la source
2

Husk , 22 octets

La manipulation des cordes n'est pas vraiment la force de Husk, mais elle a plutôt bien fonctionné:

`J"{}"J',mȯJ':msx'=fI¶

Essayez-le en ligne!

                      ¶  -- split on newlines
                    fI   -- filter by identity (ie. remove empty strings)
         m(        )     -- with each line
                x'=      -- | split on '='
              ms         -- | show each (ie. enclose in quotes and escape quotes)
           J':           -- | join with ':'
      J',                -- join these with ','
`J"{}"                   -- join the string "{}" with the result
ბიმო
la source
Ironiquement, il y a quelque chose appelé "Husk" dans Minecraft!
Programmes Redwolf
2

Rubis , 56 octets

->x{x.split(?\n).map{|i|i.split(?=)}.to_h.to_json}

+6 octets pour l' -rjsonindicateur d'interpréteur.

Essayez-le en ligne!

dkudriavtsev
la source
1
@Piccolo avez-vous passé le drapeau -rjson?
pfg
@pfg Wow, j'ai vraiment laissé tomber le ballon sur ce haha. J'avais non seulement oublié d'utiliser -rjson, mais aussi supposé sans vraiment vérifier que l'erreur était la même que celle que j'avais eue plus tôt concernantto_h
Piccolo
2

Perl 5 -nl -M5.010 , 58 54 octets

BEGIN{say'{'}s'"'\"'g;/=/&&say qq|"$`": "$'",|}{say'}'

Essayez-le en ligne!


Version 58 octets:

BEGIN{say'{'}s'"'\"'g;s/(.*)=(.*)/"$1": "$2",/;END{say'}'}

Essayez-le en ligne!

Sundar - Rétablir Monica
la source
Les deux versions ajoutent une virgule après chaque paire clé: valeur, qui n'est pas techniquement conforme JSON (la virgule finale avant la fermeture }doit être omise et échouera la plupart des validateurs JSON stricts). Voici une réécriture rapide de 58 octets qui produit un JSON valide (s'il est plus laid pour les lecteurs humains): $c||='{';s'"'\"'g;/=/&&say qq|$c"$`":"$'"|;$c=','}{say'}' Je pense que vous pouvez trouver quelque chose d'un peu plus court / plus élégant.
mousetrapper
@mousetrapper C'est une bonne façon d'éviter le BEGIN. OP autorise explicitement les virgules de fin cependant: "Les virgules de fin sont autorisées parce que Minecraft les autorise.". N'hésitez pas à poster cela comme une nouvelle réponse, en mentionnant la différence.
sundar
Ah, oui, bon point, j'ai raté cette phrase dans le message d'origine. L'affectation par défaut n'a de sens que si vous essayez de faire varier le premier caractère, sinon votre BEGINest encore plus court dans le cas où vous souhaitez simplement émettre le '{'. J'aime votre ENDtechnique évitant. Je savais que cela -nplaçait une boucle efficace while(<>){} autour de votre code; Je ne savais pas à quel point c'était littéral.
mousetrapper
J'ai également été assez surpris lorsque j'ai découvert cela pour la première fois. C'est l'une de ces fonctionnalités Perl qui chevauche la frontière entre un piratage étrange et une manière brillante de faire TIMTOWDI. Je l'avais oublié cependant, donc le mérite en revient à Dennis dans le fil de conseils de golf Perl 5 .
sundar
2

Haskell , 75 71 octets

-4 octets grâce à Laikoni (en utilisant la do-notation sur la compréhension de liste)!

Fonctionne avec plusieurs =sur une seule ligne:

f s='{':do{(a,_:b)<-span(/='=')<$>lines s;show a++':':show b++","}++"}"

Essayez-le en ligne!

Explication

Le terme span(/='=')<$>lines sdivise la chaîne sur le premier =, nous laissant avec ("<initial part>","=<remaining line>"). Faire une correspondance de modèle (a,_:b)garantit que la ligne n'était pas vide et en même temps supprime l'interlignage =.

Maintenant, nous avons seulement besoin à la showfois de ( aet de ble mettre entre guillemets et des guillemets qui s'échappent), de faire un certain formatage ( :et des ,caractères) et de l'enfermer enfin {}.

ბიმო
la source
1
71 octets en utilisant do: Essayez-le en ligne!
Laikoni
2

C (gcc) , 243 219 octets

Merci à plafondcat pour la suggestion.

J'ai décidé d'utiliser une machine d'état pour gérer les trois cas (nouvelle ligne, clé, valeur) et cela s'est plutôt bien passé. De plus, j'ai pu utiliser ab la fonction Fall-Through switchet l'opérateur de macro-chaîne!

Bien que le défi ne l'exige pas, j'ai également échappé au \personnage selon la spécification JSON. Si ce caractère ne sera jamais dans l'entrée, il &&c-92peut être supprimé pour 5 octets supplémentaires.

#define p(s)printf(#s,c)
#define a(i)case i:
c,s;f(){for(p({);(c=getchar())>0;)switch(s){a(0)if(c<11)break;s++,p(\42);a(1)c==61?s++,p(":"):p(%c);break;a(2)c-34&&c-92?c==10?p(\42\54),s=0:p(%c):p(\\%c);}s-2||p(\42);p(});}

Essayez-le en ligne!


Soumission d'origine: 243 octets

La soumission d'origine a gardé un espacement inutile comme dans les exemples JSON fournis.

#define p(s)printf(s,c)
#define a(i)case i:
c,s;f(){for(p("{\n");(c=getchar())>0;)switch(s){a(0)if(c<11)break;s++,p("  \"");a(1)c==61?s++,p("\": \""):p("%c");break;a(2)c-34&&c-39?c==10?p("\",\n"),s=0:p("%c"):p("\\%c");}s==2&&p("\"\n");p("}");}

Essayez-le en ligne!

ErikF
la source
2

JavaScript, 66 63 62 octets

s=>JSON.stringify(o=/(.+)=(.+)/g,s.replace(o,(_,a,b)=>o[a]=b))

-3 octets grâce à @redundancy

-1 octet grâce à @ l4m2

darrylyeo
la source
63 octets sur TIO
redondance
@ l4m2 Objets RegExp Stringified? J'ai appris quelque chose de nouveau aujourd'hui d
darrylyeo
1

Perl 6 , 48 octets

{to-json %(.lines.grep(?*)>>.split("=",2).flat)}

2 octets de moins si l'on peut supposer exactement 1 signe égal sur une ligne non vide.

Essayez-le en ligne!

Non golfé:

{                   # An anonymous block, taking 1 string which ends in $_.
    to-json         # Convert a Perl 6 number, string, list or hash to JSON and return it.
    %(              # Force to hash (dictionary)
        .lines      # Break $_ (implicitly assumed) into a list of lines.
        .grep(?*)   # Pick only those that are True (non-empty).
        >>.         # For each element in the list, call the following method ... 
        split("=",2) # ... split the string at =, making at most 2 chunks.
        .flat       # That gives a list of 2-element lists. Flatten it.
    )               # List is converted into the hash like this: { first element => second element, third => fourth, ... }
}                   # Implicitly return

Soit dit en passant, la to-jsonroutine est déconseillée, comme le compilateur vous le dira, mais peu importe.

Ramillies
la source
1

Rubis, 59 + 5 = 64

Besoins -rjson(+5)

->c{Hash[*c.split(?\n).map{|l|l.split ?=}.flatten].to_json}

Explication:

->c{                                                      } # anonymous function with param c
    Hash[*                                       ]          # converts ["a", "b", "c", "d"] into {"a": "b", "c": "d"}
          c.split(?\n)                                      # splits c into lines
                      .map{|l|          }                   # map lines so each element represents
                              l.split ?=                    # an array of itself but split by =
                                         .flatten           # merges 2d array to 1d (also gets rid of empty elements for newlines
                                                  .to_json  # converts hash to json
Piccolo
la source
1

JavaScript (ES6), 66 octets

s=>`{${s.replace(/"/g,'\\"').replace(/(.*)=(.*)/g,'"$1":"$2",')}}`

Suppose qu'il n'y en a qu'un =par ligne

Extrait de test

f=s=>`{${s.replace(/"/g,'\\"').replace(/(.*)=(.*)/g,'"$1":"$2",')}}`
<textarea id="i" onkeyup="o.innerText=f(i.value)"></textarea><pre id="o">

Herman L
la source
Doit être de 66 octets. \\ peut avoir été analysé comme \ lors du comptage de la longueur.
redondance
1
@redundancy Je devrais vraiment cesser d'utiliser "code".lengthdans la console javascript pour compter la longueur
Herman L
1

V , 30 octets

O{␛Í"/\\"
ggòeÉ"vyf=Plp$pa,òo}

Attend une entrée à la fois. L'extrait TIO exécute tous les cas de test donnés en une seule entrée.

Je suis nouveau dans les mappages étendus de V, donc les conseils sont toujours les bienvenus!

Essayez-le en ligne!

Explication

O{␛                  # insert { on a new line above
   Í                 # global substitution across all lines
    "/\\"            #   " => \"
gg                   # go to first line
  ò                  # recursively...
   e                 #   forward to end of word; if at end of line, applies to next word below
    É"               #   prepend " to first non-whitespace char
      vy             #   copy current character (i.e. ")
        f=Plp        #   paste " before and after the next =
             $pa,    #   paste " at end of line and append ,
                 ò   # ...end
                  o} # insert } on a new line below
redondance
la source
1

C (gcc) , 172 octets

#define p(s)printf(#s,c)
c,s;f(){for(p({);~(c=getchar());)s-2?c>10|s&&(s||(s+=p(\42)),c==61?s++,p(":"):p(%c)):c-34&&c-92?c==10?s=!p(\42\54):p(%c):p(\\%c);s-2||p(\42);p(});}

Essayez-le en ligne!

Basé sur l'implémentation de @ ErikF mais sans switch/case.

Version légèrement non golfée

#define p(s)printf(#s,c)
c,s;
f(){
 for(p({);~(c=getchar());)
  s-2?
   c>10|s&&(
    s||
     (s+=p(\42)),
    c==61?
     s++,
     p(":")
    :
     p(%c)
   )
  :
   c-34&&c-92?
    c==10?
     s=!p(\42\54)
    :
     p(%c)
   :
    p(\\%c);
 s-2||p(\42);
 p(});
}
plafond
la source
1

R, 118 octets

function(s){cat(paste("{",gsub("(.*)=(.*)","\"\\1\":\"\\2\",",gsub("\"","\\\\\"",gsub("\n{2,}","\n",s)),perl=T),"}"))}

Essayez-le en ligne!

Manoir du Chaos
la source
1

C (gcc) , 119 octets

#define p(s)printf(#s,c)
s;f(c){for(p({);~(c=getchar())|s;)c<11?s=s&&!p(",�"):c-61?s++||p(\42),p(\\u%04x):p(":");p(});}

Essayez-le en ligne!

l4m2
la source
1

PHP, 87 octets

preg_match_all("/^(.*)=(.*)$/m",$argn,$m);echo json_encode(array_combine($m[1],$m[2]));

Exécuter en tant que pipe avec -nRou l' essayer en ligne .

Insérer \savant $/mpour les sauts de ligne Windows; \s*si les sauts de ligne sont incertains.
Insérer Uaprès $/msi les valeurs contiennent =.

Titus
la source
1

Dart , 142 114 108 octets

f(s)=>"""{${s.replaceAll('"','\\"').replaceAllMapped(RegExp(r'(.*)=(.*)'),(m)=>'"${m[1]}":"${m[2]}",')}}""";

Essayez-le en ligne!

  • -28 octets en supprimant la fonction json.encode et en utilisant la construction de chaînes régulières
  • -6 octets en supprimant le «nouveau» mot clé et quelques espaces
  • Elcan
    la source