Pembaruan File Bahasa Minecraft

11

Di 1.13, file bahasa Minecraft diubah dari format kunci multi-line = nilai sederhana ke JSON .

Tantangan

Tulis program yang mengkonversi dari format asli mengembalikan string JSON. Input dapat diambil dengan menggunakan metode input standar, output harus json dari metode output standar

Format asli berisi baris dengan pasangan kunci = nilai, misalnya

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

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

Harus dikonversi ke satu objek JSON besar dengan kunci = nilai

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

Beberapa detail

  • Setiap JSON yang valid diizinkan selama hanya berisi pasangan kunci / nilai yang benar. Tanda koma diizinkan karena Minecraft mengizinkannya.
  • Satu-satunya hal yang harus diloloskan adalah kutipan. (Tidak ada baris baru, garis miring terbalik, atau hal-hal yang melanggar json lainnya ada dalam file bahasa sebelum 1,13)
  • Baris kosong harus diabaikan
  • Baris mengandung persis satu sama dengan

Uji Kasus

Memasukkan:

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

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

Keluaran:

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

Memasukkan:

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

Keluaran:

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

Memasukkan:

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

Keluaran:

{
    "stat.mineBlock": "%1$s Mined",
    "stat.craftItem": "%1$s Crafted",
    "stat.useItem": "%1$s Used",
    "stat.breakItem": "%1$s Depleted"
}
hal
sumber
1
Bagaimana tile.dirt.namejadinya "block.minecraft.dirt"?
Pavel
@ Pavel uuh ... whoops. Memperbaiki itu. Itu tidak disengaja
pfg
5
Apakah dijamin setiap baris tidak kosong mengandung tepat 1 =?
user202729
@ user202729 yes
pfg
3
Saya berani bertaruh bahwa Anda benar-benar membutuhkan solusi untuk masalah ini dan bermaksud menggunakannya untuk mengonversi file Anda. :)
mbomb007

Jawaban:

4

Python 3, 91 77 byte

-14 Bytes berkat OM to

Saya berpikir bahwa cetakan kamus Python akan cukup dekat dengan JSON untuk menjadikannya bahasa yang sangat kompetitif untuk tantangan ini. Namun, representasi string dari kamus python cukup berbeda dari JSON sehingga saya lebih beruntung menggunakan python built-in library JSON. Saya yakin ini bisa dilakukan dengan lebih ringkas di JavaScript.

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

Cobalah secara Online!


Edit:

Bash + Sed, 68 63 byte

Perbaikan bug berkat OMᗺ dan Night 2
-5 Bytes berkat OMᗺ

Saya menyadari bahwa itu mungkin lebih efisien byte untuk secara langsung mengkonversi teks ke JSON tanpa bundling dalam suatu objek, seperti pendekatan saya untuk solusi python. Per byte, sed adalah bahasa yang paling kuat untuk penggantian regex yang saya tahu.

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

Cobalah secara Online!

Penjelasan

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
Zachary Cotton
sumber
8
Jika Anda menjawab dalam dua bahasa yang berbeda, jangan ragu untuk mempostingnya sebagai dua jawaban terpisah.
mbomb007
Untuk jawaban bash + sed, coba gunakan -rbendera untuk sed (+3 byte) sehingga Anda tidak perlu melarikan diri dari grup penangkap (-4 byte) tio.run/##LYq7CgIxEEX7/…
user41805
4

Vim, 44 byte

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

Penjelasan:

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

Karat , 150 byte

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

Cobalah online!

Apakah lebih panjang dari Jawa?

Herman L.
sumber
2

Retina 0.8.2 , 35 byte

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

Cobalah online! Akan menjadi 34 byte di Retina 1 karena Anda dapat menggunakan, L$`.+bukan G`.dan .+. Penjelasan:

"
\"

Lepaskan kutipan.

=
": "

Perbaiki pemisah kunci / nilai. (Jika nilainya mungkin mengandung a =, gunakan 1`=dengan biaya 2 byte.)

G`.

Hapus garis kosong.

.+
    "$&",

Bungkus setiap baris dengan tanda kutip. (Kutipan dalam ditambahkan sebelumnya.)

^
{¶
$
¶}

Bungkus seluruh output dalam {}s.

Neil
sumber
2

Sekam , 22 byte

Manipulasi string sebenarnya bukan kekuatan Husk, tetapi cukup baik:

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

Cobalah online!

                      ¶  -- 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
ბიმო
sumber
Ironisnya, ada sesuatu yang disebut "Sekam" di Minecraft!
Program Redwolf
2

Ruby , 56 byte

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

+6 byte untuk -rjsonbendera juru bahasa.

Cobalah online!

dkudriavtsev
sumber
1
@Piccolo apakah Anda telah melewati flag -rjson?
pfg
@ pfg Wow, saya benar-benar menjatuhkan bola pada haha ​​itu. Saya tidak hanya lupa untuk menggunakan -rjson, tetapi juga berasumsi tanpa benar-benar memeriksa bahwa kesalahan itu sama dengan yang saya dapatkan sebelumnya melibatkanto_h
Piccolo
2

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

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

Cobalah online!


Versi 58 byte:

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

Cobalah online!

sundar - Pasang kembali Monica
sumber
Kedua versi menambahkan koma setelah setiap kunci: pasangan nilai, yang secara teknis tidak sesuai JSON (koma terakhir sebelum penutupan }harus dihilangkan dan akan gagal sebagian besar validator JSON ketat). Berikut ini adalah penulisan ulang 58 byte cepat yang menghasilkan JSON yang valid (jika lebih buruk untuk pembaca manusia): $c||='{';s'"'\"'g;/=/&&say qq|$c"$`":"$'"|;$c=','}{say'}' Saya berharap Anda dapat menemukan sesuatu yang sedikit lebih pendek / lebih elegan.
perangkap tikus
@mousetrapper Itu cara yang bagus untuk menghindari BEGIN. OP secara eksplisit memungkinkan koma koma: "Trailing koma diizinkan karena Minecraft mengizinkannya." Jangan ragu untuk memposting itu sebagai jawaban baru, menyebutkan perbedaannya.
sundar - Reinstate Monica
Ah, ya, poin bagus, melewatkan kalimat itu di pos asli. Tugas default hanya masuk akal jika Anda mencoba memvariasikan karakter pertama, jika tidak, Anda BEGINmasih lebih pendek dalam kasus di mana Anda hanya ingin memancarkan '{'. Saya suka ENDteknik -menghindari Anda . Saya tahu bahwa -nmenempatkan loop efektif di while(<>){} sekitar kode Anda; Saya tidak tahu seberapa literal itu.
perangkap tikus
Saya juga cukup terkejut, ketika saya pertama kali mengetahui hal itu. Ini salah satu fitur Perl yang melintasi garis antara peretasan aneh dan cara yang brilian untuk melakukan TIMTOWDI. Saya sudah lupa tentang hal itu, jadi kredit untuk ini dalam kasus ini jatuh ke Dennis di utas tips golf 5 Perl .
sundar - Reinstate Monica
2

Haskell , 75 71 byte

-4 bytes terima kasih kepada Laikoni (menggunakan notasi atas daftar-pemahaman)!

Bekerja dengan banyak =pada satu baris:

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

Cobalah online!

Penjelasan

Istilah span(/='=')<$>lines smembagi string pada yang pertama =, meninggalkan kita ("<initial part>","=<remaining line>"). Melakukan pencocokan pola (a,_:b)memastikan bahwa garis tidak kosong dan pada saat yang sama menghilangkan garis depan =.

Sekarang kita hanya perlu showkeduanya adan b(melampirkannya dalam tanda kutip dan lolos tanda kutip), lakukan beberapa pemformatan ( :dan ,karakter) dan akhirnya menyertakannya {}.

ბიმო
sumber
1
71 byte menggunakan do: Coba online!
Laikoni
2

C (gcc) , 243 219 byte

Terima kasih kepada ceilingcat untuk sarannya.

Saya memutuskan untuk menggunakan mesin negara untuk menangani tiga kasus (baris baru, kunci, nilai) dan ternyata cukup baik. Juga, saya harus ab menggunakan jatuh-melalui fitur switchdan operator stringizing makro!

Meskipun tantangan tidak memerlukannya, saya juga lolos dari \karakter sesuai spesifikasi JSON. Jika karakter itu tidak akan pernah ada di input, maka &&c-92dapat dihapus selama 5 byte lebih.

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

Cobalah online!


Pengiriman asli: 243 byte

Pengajuan asli menjaga jarak yang tidak dibutuhkan seperti pada contoh JSON yang disediakan.

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

Cobalah online!

ErikF
sumber
2

JavaScript, 66 63 62 byte

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

-3 byte terima kasih kepada @redundancy

-1 byte terima kasih kepada @ l4m2

Darrylyeo
sumber
63 byte pada TIO
redundansi
@ l4m2 Objek Regified Stringed? Mempelajari sesuatu yang baru hari ini 🤯
darrylyeo
1

Perl 6 , 48 byte

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

2 byte lebih sedikit jika kita dapat menganggap tepat 1 sama dengan tanda pada baris yang tidak kosong.

Cobalah online!

Tidak Disatukan:

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

Ngomong-ngomong, to-jsonrutinitasnya sudah usang, seperti yang dikatakan kompiler kepada Anda, tetapi siapa yang peduli.

Ramillies
sumber
1

Ruby, 59 + 5 = 64

Kebutuhan -rjson(+5)

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

Penjelasan:

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

JavaScript (ES6), 66 byte

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

Asumsikan hanya ada satu =per baris

Cuplikan pengujian

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

Herman L.
sumber
Seharusnya 66 byte. \\ mungkin telah diuraikan sebagai \ saat menghitung panjang.
redundansi
1
@redundancy Saya benar-benar harus berhenti menggunakan "code".lengthdi javascript console untuk menghitung panjangnya
Herman L
1

V , 30 byte

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

Mengharapkan satu input pada suatu waktu. Cuplikan TIO menjalankan semua test case yang diberikan sebagai input tunggal.

Saya baru mengenal pemetaan V yang luas, jadi selalu ada kiat!

Cobalah online!

Penjelasan

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
redundansi
sumber
1

C (gcc) , 172 byte

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

Cobalah online!

Berdasarkan implementasi @ ErikF tetapi tanpa switch/case.

Versi sedikit ungolfed

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

R, 118 byte

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

Cobalah online!

Kekacauan Manor
sumber
1

C (gcc) , 119 byte

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

Cobalah online!

l4m2
sumber
1

PHP, 87 byte

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

Jalankan sebagai pipa dengan -nRatau coba online .

Masukkan \ssebelum $/muntuk linebreak Windows; \s*jika linebreak tidak pasti.
Sisipkan Usetelah $/mjika nilai mengandung =.

Titus
sumber
1

Dart , 142 114 108 byte

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

Cobalah online!

  • -28 byte dengan menyingkirkan fungsi json.encode dan menggunakan string building biasa
  • -6 byte dengan menghapus kata kunci 'baru' dan beberapa spasi
  • Elcan
    sumber