Introduction
In my CS4 class I worked with another student to golf this lab as much as possible. I learned a lot about Ruby with it, and I am curious what optimizations could be done. :D
Challenge
A 3rd grade class is learning about odd and even numbers. To reinforce the concept, the teacher had the students write the odd numbers an odd number of times per line like so:
1
3 5 7
9 11 13 15 17
19 21 23 25 27 29 31
Notice the first line has 1 number, the next line 3, the next 5, and so forth containing all odd numbers in sequential order.
Given the number of odd numbers in a line, you are expected to write a program that will give the sum of the last 3 numbers of that line.
Input
The input is a sequence of lines, each having a single odd number N, where (1 < N < 100). N denotes the number of odd numbers in that particular line.
Output
For each value of N, you will print the sum of the last 3 odd numbers in that line.
Example Input
3
5
7
Example Output
15
45
87
My best attempt is 26 characters, and this took a lot of little optimizations.
I recommend working on this yourself, but here's our solution:
$<.map{p~_1.to_i**2*3/2-9}
12 Answers 12
Google Sheets, 15 bytes
=(A1+1)^2*3/2-9
Assumes flexible input. Put \$N\$ in cell A1 and the formula in cell B1. Uses the logic shown in the spoiler. Doesn't cover the case \$N = 1\$ as that doesn't seem to be required by the rules. To cover that case (22 bytes):
=max(1,(A1+1)^2*3/2-9)
05AB1E, 7 bytes
>n3;*9-
Uses the same formula as other answers.
I/O as a list.
Of course, the order of these operands can be changed slightly for the same byte-count and result:
>n6-3;*
Explanation:
> # Increase each value in the (implicit) input-list by 1
n # Square each
3* # Multiply each by 3
; # Halve each
9- # Subtract 9 from each
# (after which the resulting list is output implicitly)
6- # Subtract 6 from each
3;* # Multiply each by 1.5 (3 halved)
Dyalog APL, (削除) 14 (削除ここまで) (削除) 13 (削除ここまで) 12 bytes
-1 bytes thanks to @Tbw turning it into a tacit function -1 bytes thanks to @att mathing hard
New explanation:
×ばつ⍨++⍨-5⍨
+⍨ # N+N
- # minus
5⍨ # just 5, as a function (for the train's sake)
+ # Plus
×ばつ⍨ # N^2
×ばつ # Times
1.5 #
💎
Created with the help of Luminespire.
Original explanation:
×ばつ2*⍨1+⊢
1+⊢ # 1 plus the input
2*⍨ # to the power of (backwards) 2
×ばつ # times 1.5
💎
Created with the help of Luminespire.
-
1\$\begingroup\$ -1 byte by being tacit:
9-⍨1.5×2*⍨1+⊢\$\endgroup\$Tbw– Tbw2025年09月23日 14:00:00 +00:00Commented Sep 23 at 14:00 -
1\$\begingroup\$ Thanks @Tbw; I got so fixated on doing
×⍨for squaring but then couldn't figure out how to get that into the rest of a tacit function. \$\endgroup\$Aaron– Aaron2025年09月23日 19:12:16 +00:00Commented Sep 23 at 19:12 -
-
\$\begingroup\$ FOILed again. Thanks @att \$\endgroup\$Aaron– Aaron2025年10月01日 22:57:34 +00:00Commented Oct 1 at 22:57
x86_64 machine code, 14 bytes
0: 8d 47 01 lea eax,[rdi+0x1]
3: d1 e8 shr eax,1
5: f6 e0 mul al
7: 6b c0 06 imul eax,eax,0x6
a: 83 e8 09 sub eax,0x9
d: c3 ret
(M+1)>>1 converts an odd number M (the input) to it's ordinal placement in the series of odd numbers (i.e. 1 = 1, 3 = 2, 5 = 3, ect)
((n*n)*2)-1 gives the last number on the nth line (which corresponds to the ordinal placement of the number of elements in the line, since line 1 has 1 element, line 2 has 3, line 3 has 5, and so on) (i.e. 2 = 7, 3 = 17, 4 = 31)
Calculating the sum of the last 3 numbers on line n given the last number i is simply i + (i - 2) + (i - 4). Noting that the calculation for i ends in -1 we can move that out of i to give (i - 1) + (i - 3) + (i - 5) which can be simplified to (i*3)-9. Expanding i to ((n*n)*2) then gives ((n*n)*2*3)-9 = ((n*n)*6)-9.
Thus, the solution:
; convert input to ordinal placement
lea eax, [rdi+1]
shr eax
; square ordinal placement = i
mul al
; (i*6)
imul eax, eax, 6
; (i*6)-9
sub eax, 9
ret
Works for (odd) line lengths between 3 and 509 inclusive, due to the use of mul al (al * al -> ax), since 509 is the 255th odd number and the next one (511, the 256th) would no longer fit in al. Because we only need to be able to handle odd inputs between 1 and 100 (and it seems unspecified what to do for n == 1) this is fine.
-
\$\begingroup\$
((n*n)*6)-9does not produce the correct output for input n, per the examples in the question. This appears to arise from misconstruing the question. It does not ask to compute the sum of the last numbers of the nth line. Rather, it asks to compute the sum of the last numbers of the line containing exactly n numbers. \$\endgroup\$John Bollinger– John Bollinger2025年09月25日 19:55:47 +00:00Commented Sep 25 at 19:55 -
\$\begingroup\$ @JohnBollinger Yes, that's exactly why the first step is to convert the odd number to it's ordinal placement in the series of odd numbers. I realise I did a small amount of slight of hand in renaming
n, in the first conversion it refers to the number of elements on the line, then afterwards refers to the ordinal position. I'll edit the answer to make that clearer. \$\endgroup\$user129008– user1290082025年09月26日 14:07:16 +00:00Commented Sep 26 at 14:07
-
\$\begingroup\$ Undefined behaviour. The calculated value is undefined. \$\endgroup\$gnasher729– gnasher7292025年09月23日 21:42:58 +00:00Commented Sep 23 at 21:42
-
1\$\begingroup\$ @gnasher729 codegolf.meta.stackexchange.com/questions/5486/… \$\endgroup\$jdt– jdt2025年09月24日 00:33:40 +00:00Commented Sep 24 at 0:33
-
\$\begingroup\$ How about using a statement expression instead, and specifying the language as GNU C? That shaves two bytes and gives you something that is well defined in the specified language (dialect). \$\endgroup\$John Bollinger– John Bollinger2025年09月25日 20:12:36 +00:00Commented Sep 25 at 20:12
-
\$\begingroup\$ @JohnBollinger statement expressions looks interesting, but I'm not sure how to apply it to this example?
#define f(n){...}? \$\endgroup\$jdt– jdt2025年09月25日 22:25:21 +00:00Commented Sep 25 at 22:25
-
2
Ecmascript, (削除) 15 (削除ここまで) 14 bytes
n=>3*++n*n/2-9
-
\$\begingroup\$ Why need u
**2than*n? \$\endgroup\$l4m2– l4m22025年09月29日 09:37:49 +00:00Commented Sep 29 at 9:37 -
1\$\begingroup\$ @l4m2, because it's
++n**2, as a shorter stand-in for(n+1)**2. The alternative with multiplication is notn*n, but rather(n+1)*(n+1). \$\endgroup\$John Bollinger– John Bollinger2025年09月29日 13:42:39 +00:00Commented Sep 29 at 13:42 -
4\$\begingroup\$ The alternative is
++n*n, the second use ofnis incremented \$\endgroup\$l4m2– l4m22025年09月30日 03:50:32 +00:00Commented Sep 30 at 3:50 -
\$\begingroup\$ I see what you mean, @l4m2. Thanks. \$\endgroup\$John Bollinger– John Bollinger2025年09月30日 12:22:08 +00:00Commented Sep 30 at 12:22
GolfScript, 10 bytes
This is not ruby though, but quite close to it.
~)2?3*2/9-
Explanation:
~ # take the input
) # increment by 1
2? # raise to power 2
3* # multiply by 3
2/ # divide by 2
9- # subtract 9
Uiua, 25 bytes
A naive implementation that actually sums the last 3 odd numbers. I like its basic "1-2-3" look:
/+↙ ×ばつ2⇡n2÷2+1
Walkthrough
/+↙ ×ばつ2⇡n2÷2+1
÷2+1 # convert line length (3,5,7) to line number (2,3,4)
n2 # square it to derive sequence length N
×ばつ2⇡ # convert to range of first N odd numbers
↙ ̄3 # take last 3 elements
/+ # calculate their sum
p\$\endgroup\$