6
\$\begingroup\$

I have the code:

marks = tuple(tuple((input("Enter subject: "), input("Enter marks: "))) for _ in range(int(input("Enter number of tuples: "))))
print(tuple((s[:3].upper(), max(int(m) for t, m in marks if t == s)) for s in set(t for t, m in marks)))
#INPUT
(("Physics",131),("Chemistry",30),("Physics",100),("Computers",50),("Chemistry",20))
#OUTPUT
(('COM', 50), ('PHY', 131), ('CHE', 30))

As you can see, the output is a nested tuple of the first three capitalized letters of the subject and the maximum mark given for each subject.

You can assume that Physics, Chemistry and Computers are the only subjects that the user inputs, and that they always use the same spelling for the subjects.

The order of the subjects in the output does not matter.

Is there anyway I can do the same without using the max function? The length of the code should optimally be at 2 lines or if at all possible, a single line. The maximum limit of the number of lines of code is 3.

The solution should try to contain no built in functions if possible. Functions like sort(), sorted() and max() are strictly not allowed.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ You can replace tuple(x) with (*x,) to save some bytes \$\endgroup\$ Commented Mar 21, 2023 at 13:41

2 Answers 2

5
\$\begingroup\$

1 line, 180 173 171 bytes

7 bytes saved thanks to Jonathan Allen

exec("x={}\n"+"if x.get(a:=input('Enter subject: ')[:3].upper(),b:=int(input('Enter marks: ')))<=b:x[a]=b\n"*int(input("Enter number of tuples: "))+"print((*x.items(),))")

Attempt This Online!

3 lines, 171 163 160 bytes

8 bytes saved thanks to Jonathan Allen

x,i,e={},input,'Enter '
exec("if x.get(a:=i(e+'subject: ')[:3].upper(),b:=int(i(e+'marks: ')))<=b:x[a]=b\n"*int(i(e+"number of tuples: ")))
print((*x.items(),))

Attempt This Online!

Here's another approach that yields fewer bytes. It can be done in 1, 2 or 3 lines, with more lines enabling shorter overall programs. There's probably still even some improvements to be made here.

\$\endgroup\$
4
  • \$\begingroup\$ Depending on the rules, you might be able to replace the last print with i \$\endgroup\$
    – naffetS
    Commented Mar 26, 2023 at 13:49
  • \$\begingroup\$ I mean, the second one can be one line too, just replace the newlines with semicolons \$\endgroup\$
    – naffetS
    Commented Mar 26, 2023 at 13:56
  • \$\begingroup\$ @naffetS I don't think that's really what is meant by lines. \$\endgroup\$
    – Wheat Wizard
    Commented Mar 26, 2023 at 14:00
  • \$\begingroup\$ 158 for the second one \$\endgroup\$
    – naffetS
    Commented Mar 26, 2023 at 14:02
4
\$\begingroup\$

Python, 204 188 bytes

-16 bytes thanks to @WheatWizard

m=[*((input("Enter subject: "),int(input("Enter marks: ")))for _ in'*'*int(input("Enter number of tuples: ")))]
print((*((i[:3].upper(),j)for i,j in m if all(y!=i or z<=j for y,z in m)),))

Attempt This Online!

Python, 212 bytes

1 line

print((*[m:=[*((input("Enter subject: "),int(input("Enter marks: ")))for _ in range(int(input("Enter number of tuples: "))))]][:0],*((i[0][:3].upper(),i[1])for i in m if all(z[0]!=i[0]or z[1]<=i[1]for z in m)),))

Attempt This Online!

These are just some trivial golfs on your approach. It could probably be made much shorter. If there are ties this will print both.

\$\endgroup\$
7

Your Answer

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

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