4
\$\begingroup\$

Note: all array references in this post are zero-indexed.

When playing the piano, two notes on the same key must be pressed with two different fingers. You could use the same finger, but it doesn't sound as good. At least, according to my piano teacher. I can't hear any difference.

The challenge is to take a space-separated list of 3 integers: Starting finger, ending finger, and length of repeating notes, and output the optimal sequence of finger numbers to match the input.

All piano jargon aside, output a string of numbers based on the input, where each number is +1/-1 the one before it, all numbers are between 1 and 5, the sequence is args[2] digits long, starting with args[0] and ending with args[1], and is formatted as below.

The input can be command line arguments, values on the stack (for ><> users), STDIN, or any other conventional method.

Output will be a list of numbers, with these being valid outputs.

  • [1, 2, 3, 4, 5]
  • (1 2 3 4 5)
  • "12345"
  • 12345*
  • 1-2-3-4-5**
  • 1 2 3 4 5**

For each asterisk on the style above, compute the following to calculate your score:

final-score = code.length * (1.00 - (asterisks * 0.05));

You can assume the first two params will be between 1 and 5, but if it handles at least 0-9, multiply your code by 95%.

If the last digit is less than 2, or the input parameters are impossible, error however you like, or just exit.


Finger numbers on the piano work like this, however this is not integral to the challenge.

1 | Thumb
2 | Index finger
3 | Middle finger
4 | Ring finger
5 | Pinky (finger)

Sample input and output:

Input: 1 2 2
Output: 1 2

Input: 1 4 8
Output: 1 2 3 2 3 2 3 4

Input: 2 3 10
Output: 2 3 2 3 2 3 2 3 2 3

Input: 5 2 1
Output: Error

Input: 1 2 5
Output: Error

Input: 5 1 5
Output: 5 4 3 2 1

Input: 1 1 1
Output: 1


These do not have to be handled correctly.

Input: 1 6 6
Output: 1 2 3 4 5 6

Input: 0 9 8
Output: Error

\$\endgroup\$
  • \$\begingroup\$ I had the scoring wrong, everyone who's posted an answer please fix it. I'm really sorry D: \$\endgroup\$ – clap Sep 3 '15 at 3:59
  • \$\begingroup\$ You can just divide your score by 100 to get the new score, at least with no bonuses \$\endgroup\$ – clap Sep 3 '15 at 4:01
  • \$\begingroup\$ You may want to add an example where the end value is smaller than the start value (which seems legal based on the description). For example, 4 1 8, with possible solution 4 3 2 3 2 3 2 1. \$\endgroup\$ – Reto Koradi Sep 3 '15 at 4:31
  • \$\begingroup\$ yes, that's legal, I just forgot. thanks \$\endgroup\$ – clap Sep 3 '15 at 4:34
4
\$\begingroup\$

Pyth, 36 * .95 * .90 = 30.78

jd+JrFAQ<*vz,H.xeJhH?&%K-vzlJ2>K0K.q

Test suite

Outputs space separated integers and can handle arbitrary integer inputs, so it qualifies for both bonuses.

Input format:

length
starting finger, ending finger

The output is constructed by starting with a range from the starting finger to the ending finger, then repeating the end of that range and the ending finger the necessary number of times. Exiting is done via explicit checks for the length of the second step being odd and positive, or else .q, Pyth's exit function is called.

\$\endgroup\$
  • \$\begingroup\$ I get part of the output in square brackets when I run the examples using the test link. \$\endgroup\$ – Reto Koradi Sep 3 '15 at 6:12
  • 1
    \$\begingroup\$ It was a bug with the update to the Pyth interpreter. I fixed it. @RetoKoradi \$\endgroup\$ – isaacg Sep 3 '15 at 6:17
2
\$\begingroup\$

Javascript (ES6), 148 146 * 0.95 * (1.00 - (0 * 0.05)) = 138.7

(a,b,c)=>c<(m=Math.abs(a-b))?0:eval('l=a,q=Array(m+1).fill().map(_=>a<b?l++:l--);while(q.length-c)q=q.concat(q.slice(-2,-1));q[q.length-1]-b?0:q')

Note: My way of indicating an "error" is returning 0 (chosen to save bytes of course).

The normal return type is a Javascript array. I'm not sure if that's an acceptable output format. If it isn't, I guess I'll have to add JSON.stringify(...).

I think I get the 5% reduction since this can technically handle any range of numbers you want.

Edit: Saved 2 bytes thanks to @Ypnypn

\$\endgroup\$
  • 1
    \$\begingroup\$ You can replace each >= with < by reversing the arguments. \$\endgroup\$ – Ypnypn Sep 3 '15 at 3:37
  • \$\begingroup\$ I can't run this with node, what am I doing wrong? It doesn't error, and the prompt goes from > to ... \$\endgroup\$ – clap Sep 3 '15 at 4:03
  • \$\begingroup\$ @ConfusedMr_C Even node --harmony doesn't yet support lambdas afaik. Try it in the latest version of Firefox. \$\endgroup\$ – DankMemes Sep 3 '15 at 4:10
1
\$\begingroup\$

CJam, 50 bytes * 0.9 * 0.95 = 42.75

q~_$_@<\~),>@1$,-_0<1$2%e|{];}{2/1$-2>*+S*\{W%}&}?

Try it online

Code length is 50 bytes. If I understand them correctly, it qualifies for all bonuses. It outputs space separated values (-10%), and works for values outside the range 1 to 5 (-5%).

The input format is:

length [startValue endValue]

The sequence produced is first the range from start value to end value, then the last 2 values repeated until the specified length is reached.

Explanation:

q~    Get and interpret input.
_$    Copy and sort start/end value pair.
_@<   Copy and compare sorted and unsorted start/end values. Will use the
      sorted one, but reverse the entire sequence at the end if the start
      value was larger than the end value.
\~    Get sorted start/end value to top, and unwrap it.
),    Generate range [0 .. endValue].
>     Slice off values to get range [startValue .. endValue].
@     Get specified number of values to top.
1$,   Get list length of values we already generated.
-     Subtract. This gives the number of values that still need to be generated.
_0<   Check if number is less than 0.
1$2%  Check if number is odd.
e|    Logical or. If one of the two conditions is true, there is no solution.
{     If branch for no solution.
  ];    Clear stack. Will produce empty output for no solution.
}     End of branch for no solution.
{     If branch for producing solution.
  2/    Divide remaining count by 2. Will repeat last two values this many times.
  1$    Copy already produced values to top.
  -2>   Slice off last 2 values.
  *     Repeat them.
  +     Add to already produced sequence.
  S*    Join with spaces.
  \     Swap condition for start value greater than end value to top.
  {W%}& Reverse sequence if needed.
}?    End of if for solution vs. no solution.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.