9
\$\begingroup\$

I'm writing a program that takes a number from input (call it x), loops from 0 to (x - 1) (let's call our iterator y) and prints \$y^x+x\$ for each y.

After the loop, it then prints "SUM: N" (without a newline) where the N is the sum of the all of the previously printed values.

How can I make the code I already have shorter?

Code (Python 3, 98 bytes):

E=print
A=int(input())
B=[]
for D in range(A):C=D**A+A;B.append(C);E(C)
E(end='SUM: '+str(sum(B)))

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Could whoever VTC'd this clarify why they think it is unclear? OP has given a fairly good description of what is expected, and has provided code to be golfed. \$\endgroup\$ Dec 1, 2021 at 0:53
  • \$\begingroup\$ Normally I'd be worried about posts that just ask "HOW DO FIX?" but this seems like a pretty good example of a Python Code to golf, And is, imo, worth keeping up as both a question and a tips question. \$\endgroup\$
    – ATaco
    Dec 1, 2021 at 0:55
  • \$\begingroup\$ Is it valid to terminate with error by taking an input that doesn't exist? If so, you can use input to print without a newline for the ending sum. \$\endgroup\$
    – xnor
    Dec 1, 2021 at 1:10
  • \$\begingroup\$ @xnor no it's not valid to end with input. \$\endgroup\$
    – Fmbalbuena
    Dec 1, 2021 at 1:55
  • 3
    \$\begingroup\$ You said "loops from 0 to x", but your code is "loops from 0 to (x-1)". \$\endgroup\$
    – tsh
    Dec 1, 2021 at 2:10

4 Answers 4

10
\$\begingroup\$

Just a different approach to reduce your code to 86 bytes. You don't need to rename the print function. The only thing you need is to first compute all the values and only then print them:

A=int(input())
B=[D**A+A for D in range(A)]
print(*B,f'SUM: {sum(B)}',sep='\n',end='')

Try it online!

\$\endgroup\$
1
8
\$\begingroup\$

My attempt, 86 79 bytes

E=print
A=int(input())
E(end='SUM: %d'%sum(E(C:=D**A+A)or C for D in range(A)))

Try it online!

Thanks to dingledooper for shaving off 7 bytes by removing the need for B.

We embed the assignment in a list comprehension for -9 bytes. print returns a falsy value, so E(C:=D**A+A)or C returns C which is collected into the generator E(C:=D**A+A)or C for D in range(A) that is passed to sum.

We also format the output with a %d to save bytes off str.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Ah well done! It looks like this method can be further reduced to 79 bytes. \$\endgroup\$ Dec 1, 2021 at 1:09
  • \$\begingroup\$ @dingledooper That's quite neat, thanks! \$\endgroup\$
    – emanresu A
    Dec 1, 2021 at 1:11
  • \$\begingroup\$ +1. Accepted; Shortest bytes possible in the CGCC answer. \$\endgroup\$
    – Fmbalbuena
    Dec 1, 2021 at 1:52
4
\$\begingroup\$

Doing it in a list comprehension is a waste of time, it seems, mainly since you have to have a separate print statement for the final sum (due to the no-newline limit).

97 bytes:

E=print
f=lambda x:[E(g:=i**x+x)or g for i in range(x)]
E(end='SUM: '+str(sum(f(int(input())))))

Instead, there's a couple changes I noted.

E=print
A=int(input())
B=[]
for D in range(A):C=D**A+A;B.append(C);E(C)
E(end='SUM: '+str(sum(B)))

First, you can do B+=[C] instead of B.append(C). That loses 5 bytes for 93. But we can also just use B as an integer and add - that saves us from having to do a sum later, so we can shave off a total of 11 for a total of 85.

E=print
A=int(input())
B=0
for D in range(A):C=D**A+A;B+=C;E(C)
E(end='SUM: '+str(B))

We can then do an inline variable assignment when printing D**A+A to save bytes as well, from C=D**A+A;B+=C;E(C) to E(G:=D**A+A);B+=G. This saves one byte, for 84 bytes.

E=print
A=int(input())
B=0
for D in range(A):E(G:=D**A+A);B+=G
E(end='SUM: '+str(B))

Lastly, calling str is long and unwieldy. There's no backticks to call repr like in Python 2, but we can just use autocasting print arguments to do it anyway. From E(end='SUM: '+str(B)) to just E('SUM: ',B,end=''). We add two single quotes and a comma, but lose out on 5 bytes from the str(), for a total of -2 and a final byte count of 83.

E=print
B=0
A=int(input())
for D in range(A):E(G:=D**A+A);B+=G
E('SUM: ',B,end='')
\$\endgroup\$
3
\$\begingroup\$

Instead of adding all the terms to a list and calling sum, it's a lot shorter to keep a running total. This gets the solution down to 85 bytes:

E=print
A=int(input())
S=0
for D in range(A):C=D**A+A;S+=C;E(C)
E(end='SUM: '+str(S))

From here, two more optimizations can be made. The first is to make use of f-strings, saving three bytes. The second is to convert the for loop to a while loop, which saves another byte. With this we get an 81-byte solution:

E=print
A=int(input())
S=D=0
while D<A:C=D**A+A;S+=C;E(C);D+=1
E(end=f'SUM: {S}')

For Python >=3.8, you can also utilize the walrus operator to save 1 more byte.

E=print
A=int(input())
S=D=0
while D<A:E(C:=D**A+A);S+=C;D+=1
E(end=f'SUM: {S}')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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