| Bytes | Lang | Time | Link |
|---|---|---|---|
| 097 | Pure bash | 160513T171050Z | F. Hauri |
| 087 | Ruby | 160513T222621Z | Value In |
| 107 | PHP | 151006T151426Z | axiac |
| 181 | Python | 151006T140706Z | Zac Crit |
| 012 | Pyth | 151005T124517Z | Maltysen |
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};}
or with exactly same length:
s=$1;shift;for((a=${#s},l=a/$#,m=a-l*$#,i=1;i<=$#;p+=q,i++)){
printf "${s:p:q=i>m?l:1+l}">${!i};}
As a function: (p= is only required for second run)
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 -g
total 12
-rw-r--r-- 1 user 4 May 13 22:09 a.txt
-rw-r--r-- 1 user 4 May 13 22:09 b.txt
-rw-r--r-- 1 user 4 May 13 22:09 c.txt
$> cat {a,b,c}.txt;echo
Dogs vs Cats
$>
All files is 4 byte len and concatenated in right order, contain "Dogs vs Cats".
$> rm *
$> dog "$(printf "%s" {0..9} {a..c})" {a..e}.txt
$> ls -g
total 20
-rw-r--r-- 1 user 3 May 13 22:09 a.txt
-rw-r--r-- 1 user 3 May 13 22:09 b.txt
-rw-r--r-- 1 user 3 May 13 22:09 c.txt
-rw-r--r-- 1 user 2 May 13 22:09 d.txt
-rw-r--r-- 1 user 2 May 13 22:09 e.txt
$> cat *;echo
0123456789abc
$>
Firsts files is 3 byte len and last only 2, concatenated by alphabetic order, contain "0123456789abc".
Explanation (ungolfing):
If you hit: declare -f dog, bash will answer:
$> 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
}
This could be written:
dog2() {
local string
local -i i oneMore partLen partQuant position
string=$1
shift
partLen=" ${#string}/$# "
oneMore=" ${#string}-partLen*$# "
for (( i=1; i<=$#; i++ )) {
if (( i <= oneMore )); then
partQuant=" partLen + 1 "
else
partQuant=partLen
fi
printf "${string:position:partQuant}" > ${!i};
position+=partQuant
}
}
Note: by using local -i, I could avoid $(( .. ))!
Ruby, 93 87 bytes
Full program using command line arguments.
If I could use s.slice! to mutate the string, I'd do that instead of needing to use s[c..-1], but Ruby doesn't let you mutate the strings from argv without duplicating them first
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]}
PHP, 107 bytes
The golfed code:
for($i=1;++$i<$argc;fputs(fopen($argv[$i],w),substr($s=$argv[1],($i-2)*$l=ceil(strlen($s)/($argc-2)),$l)));
The detailed 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
}
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
Pyth - 12 bytes
.wMC,cl.zz.z
Uses builtin split function and then uses splat-map on the write function. Doesn't work online.