> 1
> InputAll
>> ∪2
>> #2
>> #3
>> 4÷5
>> ⌊6⌋
>> L⋅7
>> Each 8 3
>> 9ᴺ
>> 2ᴺ
>> 10=11
>> 6>1
>> 12⋅13
>> Output 14
###########################00000000000000000000000000001111111111111111111112222222222222222222222222333333333333333333333333334444444444444444444444444445555555555555555555555555555666666666666666666666666666777777777777777777777777777788888888888888888888888888889999999999999999999999999999============================AAAAAAAAAAAAAAAAAAAAAAAAAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEIIIIIIIIIIIIIIIIIIIIIIIIIIIILLLLLLLLLLLLLLLLLLLLLLLLLLLLOOOOOOOOOOOOOOOOOOOOOOOOOOOOaaaaaaaaaaaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccchhhhhhhhhhhhhhhhhhhhhhhhhhhhlllllllllllllllllllllllllllnnnnnnnnnnnnnnnnnnnnnnnnnnnnpppppppppppppppppppppppppppttttttttttttttttttttttttttuuuuuuuuuuuuuuuuuuuuuuuuuu÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷÷ᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺᴺ∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪∪⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌊⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋⌋
Try it online!
* Golfs made while explaining it. You can see the original here
Interesting task, fairly boring restriction.
Unfortunately, due to the fact that every line must start with either >>
or >
, this forces the number of each character to be disproportionately large. Luckily, Whispers ignores every line that doesn't match one of its regexes, all of which require the line to begin with >
. Therefore we just have a large character dump at the end of the program. In addition to this, Whispers, being designed for mathematical operations, struggles when applied to a array-manipulation question. Overall, this means that the task is interesting to attempt, but the source code requirements are a bit boring.
If we strip all the unnecessary characters from the program, we end up with
> 1
> InputAll
>> ∪2
>> #2
>> #3
>> 4÷5
>> ⌊6⌋
>> L⋅7
>> Each 8 3
>> 9ᴺ
>> 2ᴺ
>> 10=11
>> 6>1
>> 12⋅13
>> Output 14
Try it online!
which is the part of the code we're actually interested in.
How that works
Here we conduct two key tests: the count of each is the same and the counts are greater than 1. However, the code for these two tests are shared between them, so a complete walkthrough of the program is a more effective method of explaining this.
We start with the shared code:
> InputAll
>> ∪2
>> #2
>> #3
>> 4÷5
Here, we take the input and store it on line 2 (> InputAll
). We then create a ∪
nique version of that string (i.e. the input without duplicate characters). With our next two lines, we take the length of the untouched input (>> #2
) and the number of unique characters in the input (>> #3
). Finally, we divide the former by the latter.
Why? Let's have a look at the two inputs of aabbcc
and abbaabb
. With the first string, the division becomes 6÷3 = 2, and the second results in 7÷2 = 3.5. For non-discriminating strings, the result of this division is a) An integer and b) Greater than 1. Unfortunately, this also applies to some non-discriminating strings, such as abbccc
, so we have to perform one more test.
>> ⌊6⌋
>> L⋅7
>> Each 8 3
>> 9ᴺ
>> 2ᴺ
>> 10=11
Note: line 6 is the result of the division.
First, we take the floor of the division, because Python strings cannot be repeated a float number of times. Then we reach our Each
statement:
>> L⋅7
>> Each 8 3
3 is a reference to line 3, which contains our deduplicated input characters, so we map line 8 (>> L⋅7
) over this list. Line 8 multiplies the character being iterated over by the floor of our division (>> ⌊6⌋
). This creates an array of the deduplicated characters, repeated n times.
The results from our two previous strings, aabbcc
and abbaabb
, along with abcabc
, would be aabbcc
, aaabbb
and aabbcc
respectively. We can see that the first and last two are identical to their inputs, just with the letters shuffled around, whereas the middle one isn't (it has one less b
). Therefore, we simply sort both the input and this new string, before comparing for equality:
>> 9ᴺ
>> 2ᴺ
>> 10=11
Finally, we need to check that the number of characters in the string is 2 or greater. Luckily, the division we performed earlier will always result in a value greater than 1 if a character repeats more than once, meaning we just need to assert that line 6 is greater than 1:
>> 6>1
Now we have two booleans, one for each test. They both need to be true, so we perform a logical AND (boolean multiplication) with >> 12⋅13
, before finally outputting the final result.
4@Laikoni are we able to abuse comments to get this to work? – Magic Octopus Urn – 2018-03-01T14:36:09.623
6As a side note, I love challenges where I can use other entries to test my entry's validity. – Magic Octopus Urn – 2018-03-01T14:38:15.520
3@MagicOctopusUrn I think that he did say in the sandbox that's allowed, since it can't be observably determined. – Erik the Outgolfer – 2018-03-01T14:38:39.050
11Exactly. Even if you somehow manage to ban comments in an objective fashion, then what about unused string literals ect? Anyway, I think the scoring gives incentive to avoid comments as much as possible. – Laikoni – 2018-03-01T14:42:52.807
I wrote a program in Retina, a language that doesn't really have a conditional construct (it sort of does, but it is based on matching a regex, so the default of matching an empty string would mean everything is truthy?). Could I submit my answer if it outputs
1
for non-discriminating input and2
otherwise? – FryAmTheEggman – 2018-03-01T16:50:13.2834I get it's just a puzzle, but the conflation of "non-discriminating" with "all identifiable labeled member types existing in exactly equal parts" is mildly disturbing... To "discriminate" means "to tell the difference between", and to unfairly do this means to treat or judge someone unfairly based on seeing them as different from another class of people. Of course, keep going with the fun! – ErikE – 2018-03-01T22:06:03.563
@mbomb007 I don't understand what you mean, I was only asking about the output of our programs. – FryAmTheEggman – 2018-03-01T23:20:57.543
@FryAmTheEggman Looking at recent Retina submissions to [tag:decision-problem] challenges suggests that zero or one are acceptable as truthy/falsy values. – Laikoni – 2018-03-01T23:25:18.453
@Laikoni For several, including the most recent, they assume 0 is falsy and positive is truthy. This is the problem with using this convention, I think it's actually rather bad for languages that don't have traditional if/else constructs. There was a discussion about this not too long ago, but I don't think it got enough visibility.
– FryAmTheEggman – 2018-03-01T23:32:59.920Is accepting an array of integers that are the ASCII decimal values of the input okay? – Okx – 2018-03-02T09:46:42.147
@FryAmTheEggman Then that's also fine with me. – Laikoni – 2018-03-02T11:08:10.120
@Okx I'd say that's only acceptable if the language has no way of processing strings or arrays of characters. – Laikoni – 2018-03-02T11:09:27.980
Apparently you need to emphasise that the program also needs to be non-discriminating too. Since you've already bolded and italicized it, I'm not sure what else you could do... Maybe ALL CAPS – Jo King – 2018-03-05T05:38:31.450
"Each submission must be able to handle non-empty strings containing printable ASCII, as well as all characters appearing in the source code of the submission." -- I missed this in my initial comment. The expected result for the empty string was otherwise well-defined. Is there a particular reason you're not requiring any particular result for that? Existing answers vary in the results they give, so it's probably too late to change now. – hvd – 2018-03-05T11:27:34.380
@hvd While the definition covers the empty string it is still likely to be an edge case for many approaches to solve the challenge, and handling edge cases which are not important to the challenge is usually not fun.
– Laikoni – 2018-03-05T12:09:07.213@Laikoni The link you give is about not adding special cases. Excluding edge cases is actually adding special cases. If you think it's more fun like this, that's a good reason, but it's not supported by your link. :) – hvd – 2018-03-05T12:48:20.253
@hvd I don't see how saying that only non-empty strings need be handled, which is equivalent to saying that your program can do whatever it want when receiving the empty string as input, is in any way adding a special case. Requiring the empty string to be handled might lead to answers like
... or empty(s)
in which the empty string is a special case. Dropping this requirement still leaves all answers valid but also allows to drop the code only needed for the special case. – Laikoni – 2018-03-05T13:07:32.830@Laikoni You're trying to avoid special cases in the answers but I think the link you provided was about special cases in the challenges. But yeah, already agreed that changing the challenge now is not an option. – hvd – 2018-03-05T13:18:28.467