One day, I saw the challenge to multiply two strings and I thought I might be able to do one better.
That challenge was fake. It was elementwise maximum. It was not real multiplication. So I set out to make something real. Real division between two strings.
I quickly realized that this would make an amazing challenge, as the algorithm was surprisingly complex and interesting to implement.
I then realized that it was actually easily reduced into a mere few operations. I'm still doing the challenge, though.
Enough with the backstory. Let's go.
Method
To divide two strings, do the following, where x is the first string and y the second:
- If
xdoes not containy, return a space and a period concatenated tox.- For example,
testxandblahwould become.testx, with a space at the beginning.
- For example,
- Otherwise, return every occurrence of
yinx, a period, thenydivided byxwith every occurrence ofyremoved, with all the periods removed.- For example,
eesteststandestwould becomeestest.est.
- For example,
Challenge
Write a program or function that, given two strings via standard input, returns the first string divided by the second.
You may assume that both input strings will only contain letters between ASCII codepoints 33 and 45, and between codepoints 47 and 126 (yes, space and period are intended to be excluded), and that the operation does not require more than 10 layers of recursion.
You are not required to divide the empty string by itself.
Test cases
test, es => es. es
test, blah => .test
okayye, y => yy. y
testes, es => eses. es
battat, at => atat. at
see, es => .see
see, e => ee. e
same, same => same.
aabb, ab => ab.ab
eestestst, est => estest.est
aheahahe, aheah => aheah.aheah ah
-={}[];:"'!@#$%^&*()~`\|/.<>_+?, ^&*()~` => ^&*()~`. ^&*()~`
best, => .
Scoring
As this is code-golf, the submission with the least amount of bytes wins.
8 Answers 8
Python 2, (削除) 88 (削除ここまで) (削除) 85 (削除ここまで) (削除) 84 (削除ここまで) 77 bytes
f=lambda x,y,d='.':y in x and y*x.count(y)+d+f(y,x.replace(y,''),'')or' '+d+x
Saved
- -1 byte, thanks to LyricLy
- -7 bytes, thanks to Dead Possum
-
-
\$\begingroup\$ 77 bytes \$\endgroup\$Dead Possum– Dead Possum2018年06月08日 08:44:56 +00:00Commented Jun 8, 2018 at 8:44
-
\$\begingroup\$ @DeadPossum wow clever, thanks ;) \$\endgroup\$TFeld– TFeld2018年06月08日 08:47:14 +00:00Commented Jun 8, 2018 at 8:47
-
1\$\begingroup\$ I'm not sure of an implementation yet, but perhaps you can use the fact that
y*x.count(y)returns a falsy value to drop they in xcheck? \$\endgroup\$Mr. Xcoder– Mr. Xcoder2018年06月08日 08:50:06 +00:00Commented Jun 8, 2018 at 8:50
Java (JDK 11), 146 bytes
String f(String x,String y){int c=x.replace(y," ").split(" ",-1).length-1;return c<1?" ."+x:y.repeat(c)+"."+f(y,x.replace(y,"")).replace(".","");}
Try it online using Java 10! This TIO emulates String::repeat of Java 11 by writing Kevin Cruijssen's implementation as a helper method with the same amount of bytes.
Explanations
String f(String x,String y){ //
int c=x.replace(y," ").split(" ",-1).length-1; // Count the number of occurrences of y in x.
// replace(y," ") fixes the issue on special characters for the split hereafter
// .split(" ",-1) makes sure that there are trailing elements
return c<1
? // If there are no occurrence, return
" ."+x // " ."+x
: // Else return
y.repeat(c) // y, c times
+ "." // append a dot
+ f(y,x.replace(y,"")).replace(".",""); // y divided by x without y, and remove all dots
}
String.repeat(int) only exists since Java 11, hence the JDK 11 header. Alas and to my knowledge, there are currently no Java 11 online compiler / tester...
-
1\$\begingroup\$ For anyone wondering: Prove it indeed works by replacing
y.repeat(c)withnew String(new char[c]).replace("0円",y). \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年06月08日 09:29:14 +00:00Commented Jun 8, 2018 at 9:29 -
\$\begingroup\$ Thanks @KevinCruijssen I'll integrate that in my answer. I should have done that, actually... \$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年06月08日 09:33:27 +00:00Commented Jun 8, 2018 at 9:33
-
\$\begingroup\$ @KevinCruijssen Thank you, I've been doing this quickly on the side and didn't check better. My bad. The random ascii characters don't work probably because they contain special characters used in regex (implicitly used by
split). I'll try to fix this. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年06月08日 09:51:49 +00:00Commented Jun 8, 2018 at 9:51 -
1\$\begingroup\$ How about using
x.replace(y," ").split(" ",-1)? \$\endgroup\$Jakob– Jakob2018年06月08日 18:06:09 +00:00Commented Jun 8, 2018 at 18:06 -
1\$\begingroup\$ Works like a charm! Thanks @Jakob, that's very imaginative! \$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年06月08日 20:26:18 +00:00Commented Jun 8, 2018 at 20:26
Python 2, 72 bytes
lambda f,s:(s*f.count(s)+'.'*(s in f))+s*(s in f)+(' .'+f)*(f.find(s)<0)
Proton, 75 bytes
f=(x,y)=>(u=x.count(y))?y*u+'.'+f(y,x.replace(y,'')).replace('.',''):' .'+x
Physica, (削除) 81 75 (削除ここまで) 67 bytes
f=>x;y;d='.':y∈x&&y*x.count[y]+d+f[y;Replace[x;y;''];'']||' '+d+x
Utilizes Dead Possum's golfs on TFeld's answer.
Retina, 105 bytes
¶.*$
$&¶.
/^(.*)¶.*1円/{*>|""L`(?<=(.*)¶.*)1円|\.$
(?<=(.*)¶.*)1円|\.$
)`(.*)¶(.*)
2ドル¶1ドル
.*¶(.*)¶(.*)
2ドル1ドル
Try it online! Link includes test suite, but code normally takes y then x on separate lines. Explanation:
¶.*$
$&¶.
Append a newline and a . This expression is cumbersome in order to deal with an empty second input, where $ would otherwise match twice.
/^(.*)¶.*1円/{
Repeat while x contains y.
*>|""L`(?<=(.*)¶.*)1円|\.$
Output all of the matches of y in x, plus the . on the first pass.
(?<=(.*)¶.*)1円|\.$
And then delete them all.
)`(.*)¶(.*)
2ドル¶1ドル
Swap over x and y and repeat.
.*¶(.*)¶(.*)
2ドル1ドル
Output the . if x never contained y, and y.
JavaScript (Babel Node), 90 bytes
Based on Olivier Grégoire Answer
(_,x)=>(l=_.match(RegExp(x,`g`)))?l.join``+`.`+f(x,_.replace(x,'')).split`.`.join``:` .`+_
atoz? 2. Why isn't the output of the first onees.tt? 3. Why is there a space after the periods in your testcases? \$\endgroup\$atoz? What exactly are the characters that will appear? Can you phrase it in a positive instead of a negative? \$\endgroup\$same.the output ofsame, same? \$\endgroup\$.testxstring reads.textxinstead. \$\endgroup\$