Implementieren Sie das Dienstprogramm Dog Bash

10

dog ist ein Befehlszeilenprogramm, das eine beliebige Anzahl von Argumenten aufnimmt, von denen das erste der zu schreibende Text ist und die anderen beliebig viele Dateien sind.

Das dogDienstprogramm teilt den Text zu gleichen Teilen auf diese Dateien auf. Wenn es einen Rest gibt n, erhalten die ersten nDateien ein zusätzliches Byte

dogist das Gegenteil von catals solches für alle, xsollte das Folgende gelten.

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

Wobei ...beliebig viele Dateien angezeigt werden.

Ein Beispiel (12 Bytes, 3 Dateien, können gleichmäßig aufgeteilt werden):

$> ./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$> 

Ein Beispiel mit Rest (13 Bytes, 5 Dateien, Rest 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
quelle
Es ist impliziert, aber nur zur Überprüfung: 1) Müssen die Argumente über die Befehlszeile eingehen? 2) Müssen wir immer in Dateien ausgeben?
Sp3000
@ Sp3000 ja, zu 1 und 2
Caridorc
1
@ DigitalTrauma gibt es bereits eine Antwort, ich würde mich schlecht fühlen, wenn ich es durch eine Regeländerung ungültig
mache
2
Ich habe in letzter Zeit auf dieser Site etwas über seltsam benannte UNIX-Dienstprogramme gelernt (tac, dog, ...).
kirbyfan64sos
1
@ kirbyfan64sos und Caridorc: tacist echt .
DLosc

Antworten:

4

Pyth - 12 Bytes

.wMC,cl.zz.z

Verwendet die integrierte Split-Funktion und dann die Splat-Map für die Schreibfunktion. Funktioniert nicht online.

Maltysen
quelle
2

Python - 181 Bytes

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

PHP, 107 Bytes

Der Golfcode:

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

Der detaillierte Code:

$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
}
Axiac
quelle
0

Pure Bash: 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};}

Als Funktion: ( p=wird nur für den zweiten Lauf benötigt)

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

Tests

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

Alle Dateien sind 4 Byte lang und in der richtigen Reihenfolge verkettet. Sie enthalten "Dogs vs Cats" .

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

Die ersten Dateien sind 3 Byte lang und die letzten nur 2, in alphabetischer Reihenfolge verkettet, enthalten "0123456789abc" .

Erklärung (ungolfing):

Wenn Sie getroffen: declare -f dog, beantworten:

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

Dies könnte geschrieben werden:

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

Ruby, 93 87 Bytes

Vollständiges Programm mit Befehlszeilenargumenten.

Wenn ich s.slice!die Zeichenfolge mutieren könnte , würde ich das tun, anstatt sie verwenden zu müssen s[c..-1], aber Ruby lässt Sie die Zeichenfolgen nicht von argv mutieren, ohne sie vorher zu duplizieren

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]}
Wert Tinte
quelle