Оновлення мовних файлів Minecraft


11

У 1.13 мовні файли Minecraft були переведені з простого багаторядкового формату ключа = значення на JSON .

Виклик

Напишіть програму, що перетворюється з вихідного формату, повертаючи рядок JSON. Введення можна приймати за допомогою будь-якого стандартного способу введення, вихід повинен бути json від будь-якого стандартного способу введення

Оригінальний формат містить, наприклад, рядки з ключами = пари

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

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

Слід перетворити на один великий об'єкт JSON з ключем = значення

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

Деякі деталі

  • Будь-який дійсний JSON дозволений, якщо він містить лише правильні пари ключ / значення. Додаткові коми допускаються, оскільки Minecraft дозволяє.
  • Єдине, чого потрібно уникати, - це цитати. (У мовному файлі до 1.13 не існувало нових рядків, зворотних косих рисоків чи інших речей, що порушують json)
  • Порожні рядки слід ігнорувати
  • Рядки містять рівно одну рівну

Випробування

Вхід:

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

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

Вихід:

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

Вхід:

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

Вихід:

{
  "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",
}

Вхід:

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

Вихід:

{
    "stat.mineBlock": "%1$s Mined",
    "stat.craftItem": "%1$s Crafted",
    "stat.useItem": "%1$s Used",
    "stat.breakItem": "%1$s Depleted"
}

1
Як це tile.dirt.nameстає "block.minecraft.dirt"?
Павло

@Pavel uuh ... whoops. Виправлено це. Це було ненавмисно
pfg

5
Чи гарантується, що кожен непустий рядок містить рівно 1 =?
користувач202729

@ user202729 так
pfg

3
Я б хотів зробити ставку, що вам справді потрібно вирішити цю проблему, і я маю намір використовувати його для перетворення ваших файлів. :)
mbomb007

Відповіді:


4

Python 3, 91 77 байт

-14 байт завдяки OMᗺ

Я думав, що роздрукування словника Python буде досить близьким до JSON, щоб зробити його дуже конкурентоспроможною мовою для цього завдання. Однак рядкове представлення словників python досить відрізняється від JSON, що мені пощастило використовувати вбудовану бібліотеку JSON python. Б'юсь об заклад, це можна зробити більш лаконічно в JavaScript.

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

Спробуйте в Інтернеті!


Редагувати:

Bash + Sed, 68 63 байт

Виправлення помилок завдяки OMᗺ та Night 2
-5 Bytes завдяки OMᗺ

Я зрозумів, що може бути більш ефективним байт безпосередньо перетворити текст в JSON, не зв'язуючи його в об'єкт, як це було в моєму підході до рішення python. Per byte, sed - це найпотужніша мова для заміни регулярних виразів, яку я знаю.

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

Спробуйте в Інтернеті!

Пояснення

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

8
Якщо ви відповідаєте двома різними мовами, сміливо публікуйте це як дві окремі відповіді.
mbomb007

Для відповіді bash + sed спробуйте використати -rпрапор sed (+3 байт), щоб вам не потрібно було уникати груп захоплення (-4 байти) tio.run/##LYq7CgIxEEX7/…
user41805

4

Vim, 44 байти

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

Пояснення:

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


2

Сітківка 0,8,2 , 35 байт

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

Спробуйте в Інтернеті! В Retina 1 буде 34 байти, як ви можете використовувати L$`.+замість G`.і .+. Пояснення:

"
\"

Уникнути цитат.

=
": "

Зафіксуйте роздільник ключа / значення. (Якщо значення може містити значення a =, використовуйте 1`=вартістю 2 байти.)

G`.

Видаліть порожні рядки.

.+
    "$&",

Загорніть кожен рядок у лапки. (Внутрішні цитати були додані раніше.)

^
{¶
$
¶}

Загорніть весь вихід у {}с.


2

Лушпиння , 22 байти

Струнні маніпуляції насправді не є силою лушпиння, але це було досить добре:

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

Спробуйте в Інтернеті!

                      ¶  -- 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

За іронією долі, у Minecraft є щось, що називається «лушпиння»!
Програми Redwolf

2

Рубін , 56 байт

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

+6 байт для -rjsonпрапора перекладача.

Спробуйте в Інтернеті!


1
@Piccolo ти передав прапор -rjson?
pfg

@pfg Ого, я справді кинув м'яч на ту ха-ха. Я не тільки забув використати -rjson, але й припустив, не перевіряючи, що помилка була та сама, з якою я потрапив ранішеto_h
Piccolo

2

Perl 5 -nl -M5.010 , 58 54 байти

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

Спробуйте в Інтернеті!


58-байтна версія:

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

Спробуйте в Інтернеті!


Обидві версії додають кому після кожної пари key: value, яка технічно не відповідає JSON (остаточна кома перед закриттям }повинна бути опущена і не матиме найсуворіших валідаторів JSON). Ось швидкий 58-байтовий перепис, який дає дійсні (якщо непривабливіші для людських читачів) JSON: $c||='{';s'"'\"'g;/=/&&say qq|$c"$`":"$'"|;$c=','}{say'}' Я сподіваюся, що ви зможете знайти щось трохи коротше / елегантніше.
мишоловка

@mousetrapper Це хороший спосіб уникнути цього BEGIN. OP явно дозволяє чітко пропускати коми: "Задні коси дозволені, тому що Minecraft дозволяє". Не соромтеся розмістити це як нову відповідь, зазначивши різницю.
sundar

Ага, так, хороший пункт, пропустив це речення в оригінальній публікації. Призначення за замовчуванням має сенс лише в тому випадку, якщо ви намагаєтесь змінити перший символ, інакше ваш показник BEGINвсе ще коротший у випадку, коли ви просто хочете випустити "{". Мені подобається ваша ENDтехніка, що сприяє. Я знав, що -nрозмістив ефективний while(<>){} цикл навколо вашого коду; Я не мав уявлення лише про те, наскільки це було буквально.
мишоловка

Я теж був дуже здивований, коли вперше дізнався це. Це одна з тих функцій Perl, яка простежує лінію між дивним хаком і блискучим способом зробити TIMTOWDI. Я забув про це, хоча, так що заслуга в цьому випадку припадає на Денніса в потоці поради щодо гольфу Perl 5 .
sundar

2

Haskell , 75 71 байт

-4 байти завдяки Laikoni (використовуючи нотацію над розумінням списку)!

Працює з кількома =в одному рядку:

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

Спробуйте в Інтернеті!

Пояснення

Термін span(/='=')<$>lines sрозділяє рядок на перший =, залишаючи нас ("<initial part>","=<remaining line>"). Виконання відповідності шаблону (a,_:b)гарантує, що рядок не був порожнім і одночасно видаляє провідну =.

Тепер нам залишається лише showі те, aі b(уклавши його в лапки і відмовитись від лапок), зробити деяке форматування ( :і ,символи) і, нарешті, укласти його {}.


1
71 байт з використанням do: Спробуйте в Інтернеті!
Лайконі

2

C (gcc) , 243 219 байт

Дякую стельовій кішці за пропозицію.

Я вирішив використовувати державну машину для обробки трьох випадків (новий рядок, ключ, значення), і це вийшло досить добре. Крім того , я повинен Абама використовувати завал через особливість switchі макро - оператор stringizing!

Незважаючи на те, що виклик цього не потребував, я також уникнув \характеру за специфікацією JSON. Якщо цей символ ніколи не буде на вході, його &&c-92можна буде видалити ще на 5 байт.

#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(});}

Спробуйте в Інтернеті!


Оригінальне подання: 243 байти

Оригінальне подання зберігало непотрібний інтервал, як у наведених прикладах JSON.

#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("}");}

Спробуйте в Інтернеті!


2

JavaScript, 66 63 62 байт

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

-3 байти завдяки @redundancy

-1 байт завдяки @ l4m2




@ l4m2 Stringified RegExp об'єкти? Дізнався чогось нового сьогодні 🤯
darrylyeo


1

Perl 6 , 48 байт

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

2 байти менше, якщо можна припустити, що рівно 1 знак дорівнює в не порожньому рядку.

Спробуйте в Інтернеті!

Безголівки:

{                   # 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

До речі, to-jsonрутина застаріла, як вам скаже компілятор, але кого це хвилює.



1

Рубі, 59 + 5 = 64

Потреби -rjson(+5)

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

Пояснення:

->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

1

JavaScript (ES6), 66 байт

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

Припускаємо, що є лише один =на рядок

Фрагмент тестування

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


Має бути 66 байт. \\, можливо, було розібрано як \ під час підрахунку довжини.
надмірність

1
@redundancy Я дійсно повинен перестати використовувати "code".lengthконсоль javascript для підрахунку довжини
Герман L,

1

V , 30 байт

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

Очікує по одному вводу за раз. Фрагмент TIO запускає всі задані тестові випадки як єдиний вхід.

Я новачок у розширених картах V, тому поради завжди раді!

Спробуйте в Інтернеті!

Пояснення

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

1

C (gcc) , 172 байт

#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(});}

Спробуйте в Інтернеті!

На основі реалізації @ ErikF, але без switch/case.

Трохи незворушена версія

#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(});
}



1

PHP, 87 байт

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

Запустіть як трубу -nRабо спробуйте в Інтернеті .

Вставити \sраніше $/mдля рядків перерв Windows; \s*якщо рядкові перерви невизначені.
Вставити Uпісля, $/mякщо значення містять =.


1

Дарт , 142 114 108 байт

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

Спробуйте в Інтернеті!

  • -28 байт, позбавившись від функції json.encode та використовуючи регулярне нарощування рядків
  • -6 байт, видаливши "нове" ключове слово та кілька пробілів
  • Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
    Licensed under cc by-sa 3.0 with attribution required.