Terapkan utilitas bash dog

10

dog adalah utilitas baris perintah yang menggunakan sejumlah argumen arbitrer, yang pertama adalah teks yang akan ditulis dan yang lainnya banyak file secara sewenang-wenang.

The dogutilitas akan membagi teks dalam porsi yang sama atas file tersebut. Jika ada sisa n, nfile pertama mendapatkan byte tambahan

dogadalah kebalikan dari cat, karena itu, secara keseluruhan x, yang berikut ini harus berlaku.

$> dog x a.txt b.txt ...
$> cat a.txt b.txt ...
x$>

Di mana ...menunjukkan banyak file sewenang-wenang.

Contoh (12 byte, 3 file, dapat dibagi secara merata):

$> ./dog.py "Dogs vs Cats" a.txt b.txt c.txt
$> cat a.txt
Dogs$> cat b.txt
 vs $> cat c.txt
Cats$> cat a.txt b.txt c.txt
Dogs vs Cats$> 

Contoh dengan sisa (13 byte, 5 file, sisa 3):

9$>./dog.py "0123456789abc" a.txt b.txt c.txt d.txt e.txt
$> cat a.txt
012$> cat b.txt
345$> cat c.txt
678$> cat d.txt
9a$> cat e.txt
bc$> cat a.txt b.txt c.txt d.txt e.txt
0123456789abc$>
Caridorc
sumber
Tersirat, tetapi hanya untuk mengecek: 1) Apakah argumen harus masuk melalui baris perintah? 2) Apakah kita selalu harus meng-output ke file?
Sp3000
@ Sp3000 ya, ke 1 dan 2
Caridorc
1
@DigitalTrauma sudah ada jawaban, saya akan merasa tidak enak karena membatalkannya dengan perubahan aturan
Caridorc
2
Saya telah belajar tentang beberapa utilitas UNIX aneh bernama dari situs ini belakangan ini (tac, dog, ...).
kirbyfan64sos
1
@ kirbyfan64sos dan Caridorc: tacasli .
DLosc

Jawaban:

4

Pyth - 12 byte

.wMC,cl.zz.z

Menggunakan fungsi split bawaan dan kemudian menggunakan splat-map pada fungsi tulis. Tidak berfungsi online.

Maltysen
sumber
2

Python - 181 byte

import sys
a=sys.argv
l=len
d=a[2:]
s=a[1]
n,r=divmod(l(s),l(d))
p=0
for i in range(l(d)):
    with open(d[i],'w') as f:
        o=n+int(i<=n)
        f.write(s[p:p+o])
        p+=o
Zac Crites
sumber
1

PHP, 107 byte

Kode golf:

for($i=1;++$i<$argc;fputs(fopen($argv[$i],w),substr($s=$argv[1],($i-2)*$l=ceil(strlen($s)/($argc-2)),$l)));

Kode terperinci:

$len = ceil(strlen($argv[1])/($argc - 2));
for ($i = 2; $i < $argc; $i ++) {
    $fh = fopen($argv[$i], 'w');
    fputs($fh, substr($argv[1], ($i - 2) * $len, $len));
    fclose($fh);          // omitted in the golfed version
}
aksioma
sumber
0

Bash murni: 97

s=$1;shift;for((l=${#s}/$#,m=${#s}-l*$#,i=1;i<=$#;p+=q,i++)){
printf "${s:p:q=i>m?l:l+1}">${!i};}

Sebagai fungsi: ( p=hanya diperlukan untuk menjalankan kedua)

dog() { p=
    s=$1;shift;for((l=${#s}/$#,m=${#s}-l*$#,i=1;i<=$#;p+=q,i++)){
    printf "${s:p:q=i>m?l:l+1}">${!i};}
}

Tes

$> rm *
$> dog "Dogs vs Cats" a.txt b.txt c.txt
$> ls -l
total 12
-rw-r--r-- 1 user user 4 May 13 22:09 a.txt
-rw-r--r-- 1 user user 4 May 13 22:09 b.txt
-rw-r--r-- 1 user user 4 May 13 22:09 c.txt
$> cat {a,b,c}.txt;echo
Dogs vs Cats
$> 

Semua file berukuran 4 byte len dan digabung dalam urutan yang benar, berisi "Anjing vs Kucing" .

$> rm *
$> dog "$(printf "%s" {0..9} {a..c})" {a..e}.txt 
$> ls -l
total 20
-rw-r--r-- 1 user user 3 May 13 22:09 a.txt
-rw-r--r-- 1 user user 3 May 13 22:09 b.txt
-rw-r--r-- 1 user user 3 May 13 22:09 c.txt
-rw-r--r-- 1 user user 2 May 13 22:09 d.txt
-rw-r--r-- 1 user user 2 May 13 22:09 e.txt
$> cat *;echo
0123456789abc
$> 

File pertama adalah 3 byte len dan hanya 2, disatukan dengan urutan abjad, mengandung "0123456789abc" .

Penjelasan (ungolfing):

Jika anda menekan: declare -f dog, akan menjawab:

$> declare -f dog
dog () 
{ 
    p=;
    s=$1;
    shift;
    for ((l=${#s}/$#,m=${#s}-l*$#,i=1; i<=$#; p+=q,i++))
    do
        printf "${s:p:q=i>m?l:l+1}" > ${!i};
    done
}

Ini dapat ditulis:

dog2 () 
{ 
    position=0;
    string=$1;
    shift;
    partLen=$((${#string}/$#));
    oneMore=$((${#string}-partLen*$#));
    for ((i=1; i<=$#; i++))
    do
        if ((i<=oneMore)); then
            partQuant=$((partLen+1));
        else
            partQuant=$partLen;
        fi;
        printf "${string:position:partQuant}" > ${!i};
        ((position+=partQuant));
    done
}
F. Hauri
sumber
0

Ruby, 93 87 byte

Program penuh menggunakan argumen baris perintah.

Jika saya bisa menggunakan s.slice!untuk memutasi string, saya akan melakukan itu alih-alih perlu digunakan s[c..-1], tetapi Ruby tidak membiarkan Anda mengubah string dari argv tanpa menduplikasi terlebih dahulu.

s,*t=$*
d,r=s.size.divmod t.size
t.map{|e|open(e,?w)<<s[0,c=(0>r-=1)?d:d+1];s=s[c..-1]}
Nilai Tinta
sumber