4
\$\begingroup\$

My code is working but it is extremely long. So, I guess there is a way to make it shorter/more efficient.

The problem solved here is from Advent of Code 2021, Day 3, Part 1: https://adventofcode.com/2021/day/3

binary_list = open("data.txt").read().split("\n")

counter_1st_bit_0 = 0
counter_1st_bit_1 = 0

counter_2nd_bit_0 = 0
counter_2nd_bit_1 = 0

counter_3rd_bit_0 = 0
counter_3rd_bit_1 = 0

counter_4th_bit_0 = 0
counter_4th_bit_1 = 0

counter_5th_bit_0 = 0
counter_5th_bit_1 = 0

counter_6th_bit_0 = 0
counter_6th_bit_1 = 0

counter_7th_bit_0 = 0
counter_7th_bit_1 = 0

counter_8th_bit_0 = 0
counter_8th_bit_1 = 0

counter_9th_bit_0 = 0
counter_9th_bit_1 = 0

counter_10th_bit_0 = 0
counter_10th_bit_1 = 0

counter_11th_bit_0 = 0
counter_11th_bit_1 = 0

counter_12th_bit_0 = 0
counter_12th_bit_1 = 0


gamma_rate_queue = []
epsilon_rate_queue = []


for i in range(0, len(binary_list), 1):
  for j in range(0, len(binary_list[i]), 1):

    if binary_list[i][0] == "0":
      counter_1st_bit_0 += 1
    elif binary_list[i][0] == "1":
      counter_1st_bit_1 += 1

    if binary_list[i][1] == "0":
      counter_2nd_bit_0 += 1
    elif binary_list[i][1] == "1":
      counter_2nd_bit_1 += 1

    if binary_list[i][2] == "0":
      counter_3rd_bit_0 += 1
    elif binary_list[i][2] == "1":
      counter_3rd_bit_1 += 1

    if binary_list[i][3] == "0":
      counter_4th_bit_0 += 1
    elif binary_list[i][3] == "1":
      counter_4th_bit_1 += 1

    if binary_list[i][4] == "0":
      counter_5th_bit_0 += 1
    elif binary_list[i][4] == "1":
      counter_5th_bit_1 += 1

    if binary_list[i][5] == "0":
      counter_6th_bit_0 += 1
    elif binary_list[i][5] == "1":
      counter_6th_bit_1 += 1

    if binary_list[i][6] == "0":
      counter_7th_bit_0 += 1
    elif binary_list[i][6] == "1":
      counter_7th_bit_1 += 1

    if binary_list[i][7] == "0":
      counter_8th_bit_0 += 1
    elif binary_list[i][7] == "1":
      counter_8th_bit_1 += 1

    if binary_list[i][8] == "0":
      counter_9th_bit_0 += 1
    elif binary_list[i][8] == "1":
      counter_9th_bit_1 += 1

    if binary_list[i][9] == "0":
      counter_10th_bit_0 += 1
    elif binary_list[i][9] == "1":
      counter_10th_bit_1 += 1

    if binary_list[i][10] == "0":
      counter_11th_bit_0 += 1
    elif binary_list[i][10] == "1":
      counter_11th_bit_1 += 1

    if binary_list[i][11] == "0":
      counter_12th_bit_0 += 1
    elif binary_list[i][11] == "1":
      counter_12th_bit_1 += 1


def gamma_rate_finder():

  if counter_1st_bit_0 > counter_1st_bit_1:
    gamma_rate_queue.append('0')
  elif counter_1st_bit_0 < counter_1st_bit_1:
    gamma_rate_queue.append('1')

  if counter_2nd_bit_0 > counter_2nd_bit_1:
    gamma_rate_queue.append('0')
  elif counter_2nd_bit_0 < counter_2nd_bit_1:
    gamma_rate_queue.append('1')

  if counter_3rd_bit_0 > counter_3rd_bit_1:
    gamma_rate_queue.append('0')
  elif counter_3rd_bit_0 < counter_3rd_bit_1:
    gamma_rate_queue.append('1')

  if counter_4th_bit_0 > counter_4th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_4th_bit_0 < counter_4th_bit_1:
    gamma_rate_queue.append('1')

  if counter_5th_bit_0 > counter_5th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_5th_bit_0 < counter_5th_bit_1:
    gamma_rate_queue.append('1')

  if counter_6th_bit_0 > counter_6th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_6th_bit_0 < counter_6th_bit_1:
    gamma_rate_queue.append('1')

  if counter_7th_bit_0 > counter_7th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_7th_bit_0 < counter_7th_bit_1:
    gamma_rate_queue.append('1')

  if counter_8th_bit_0 > counter_8th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_8th_bit_0 < counter_8th_bit_1:
    gamma_rate_queue.append('1')

  if counter_9th_bit_0 > counter_9th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_9th_bit_0 < counter_9th_bit_1:
    gamma_rate_queue.append('1')

  if counter_10th_bit_0 > counter_10th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_10th_bit_0 < counter_10th_bit_1:
    gamma_rate_queue.append('1')

  if counter_11th_bit_0 > counter_11th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_11th_bit_0 < counter_11th_bit_1:
    gamma_rate_queue.append('1')

  if counter_12th_bit_0 > counter_12th_bit_1:
    gamma_rate_queue.append('0')
  elif counter_12th_bit_0 < counter_12th_bit_1:
    gamma_rate_queue.append('1')

  gamma_rate = ''.join(gamma_rate_queue)

  return gamma_rate


def epsilon_rate_finder():

  if counter_1st_bit_0 < counter_1st_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_1st_bit_0 > counter_1st_bit_1:
    epsilon_rate_queue.append('1')

  if counter_2nd_bit_0 < counter_2nd_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_2nd_bit_0 > counter_2nd_bit_1:
    epsilon_rate_queue.append('1')

  if counter_3rd_bit_0 < counter_3rd_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_3rd_bit_0 > counter_3rd_bit_1:
    epsilon_rate_queue.append('1')

  if counter_4th_bit_0 < counter_4th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_4th_bit_0 > counter_4th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_5th_bit_0 < counter_5th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_5th_bit_0 > counter_5th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_6th_bit_0 < counter_6th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_6th_bit_0 > counter_6th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_7th_bit_0 < counter_7th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_7th_bit_0 > counter_7th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_8th_bit_0 < counter_8th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_8th_bit_0 > counter_8th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_9th_bit_0 < counter_9th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_9th_bit_0 > counter_9th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_10th_bit_0 < counter_10th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_10th_bit_0 > counter_10th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_11th_bit_0 < counter_11th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_11th_bit_0 > counter_11th_bit_1:
    epsilon_rate_queue.append('1')

  if counter_12th_bit_0 < counter_12th_bit_1:
    epsilon_rate_queue.append('0')
  elif counter_12th_bit_0 > counter_12th_bit_1:
    epsilon_rate_queue.append('1')

  epsilon_rate = ''.join(epsilon_rate_queue)

  return epsilon_rate


binary_gamma_rate = gamma_rate_finder()
binary_epsilon_rate = epsilon_rate_finder()


def Binary_to_DecimalValue(n):
  b_num = list(n)
  value = 0
  for i in range(len(b_num)):
      digit = b_num.pop()
      if digit == '1':
          value = value + pow(2, i)
  return value


gamma_rate = Binary_to_DecimalValue(binary_gamma_rate)
epsilon_rate = Binary_to_DecimalValue(binary_epsilon_rate)


PowerConsumption = gamma_rate * epsilon_rate

print("Gamma rate is: {} | {}".format(gamma_rate, binary_gamma_rate) + "\n" + "Epsilon rate is: {} | {}".format(epsilon_rate, binary_epsilon_rate) + "\n" + "The Power Consumption is: {}".format(PowerConsumption))

Any advice about my code would be helpful, I guess there is a way to replace lists here and to make the loops and functions more efficient.

Thanks.

\$\endgroup\$
5
  • \$\begingroup\$ This seems like a very hardcoded way to go about things. For starters, I see a lot of if that should've been elif. What version of Python did you write this for? \$\endgroup\$
    – Mast
    Dec 4 '21 at 21:47
  • 1
    \$\begingroup\$ Why do you stop on 12th bit? \$\endgroup\$
    – vnp
    Dec 4 '21 at 22:28
  • \$\begingroup\$ @vnp is appears that the sample given only has twelve lines of input. But it's not guaranteed for the puzzle input that I can see. @zаѓатhᵾѕтѓа Generally speaking, if you have variable names like ...5th..., you need to step back and think if you should be using a list instead. And for i in range(len(somelist)) is almost always the wrong approach. \$\endgroup\$
    – Teepeemm
    Dec 4 '21 at 23:09
  • 1
    \$\begingroup\$ @vnp For context, the input to this problem is randomized per user but the format of that input is constant: a list of 1,000 12-digit binary numbers. Which does justify hard-coding 12 here since the input will never contain a binary number that is not 12 digits long. \$\endgroup\$
    – Setris
    Dec 5 '21 at 0:03
  • \$\begingroup\$ I am using Python 3.8.2, thanks everyone. \$\endgroup\$ Dec 5 '21 at 13:31
7
\$\begingroup\$

I'm just going to make one suggestion, which you should be able to apply across a lot of your code.

  1. Use list structures, which are analogous to arrays in other languages.

That's it. Lists.

Use lists for counting values

Your first use should be to replace the 0/1 variables in counting code:

counter_1st_bit_0 = 0
counter_1st_bit_1 = 0

Let's make those two variables into a single list with two elements:

counter_1st_bit = [0, 0]

(Note: the [0, 0] syntax is a list literal. These things are so common that Python supports typing them directly into the code.)

Now you can access counter_1st_bit[0] and counter_1st_bit[1] as two separate values (which they are!) and update them based on your input:

if binary_list[i][0] == "0":
  counter_1st_bit[0] += 1
elif binary_list[i][0] == "1":
  counter_1st_bit[1] += 1

Once you make that change, you can go one step farther and convert the string value to an integer value:

bit = int(binary_list[i][0])
if bit == 0:
    counter_1st_bit[0] += 1
elif bit == 1:
    counter_1st_bit[1] += 1

Then you realize that the bit value can only be either 0 or 1, so it's not if / elif but rather if / else:

bit = int(binary_list[i][0])
if bit == 0:
    counter_1st_bit[0] += 1
else:
    counter_1st_bit[1] += 1

And then you realize that the 0 and 1 are the values of bit:

bit = int(binary_list[i][0])
if bit == 0:
    counter_1st_bit[bit] += 1
else:
    counter_1st_bit[bit] += 1

And then you realize that the statements are the same, so you don't need the if and else:

bit = int(binary_list[i][0])
counter_1st_bit[bit] += 1

Now you're cooking with gas! Because you're only using the bit value one time, in one place, you can get rid of that variable:

counter_1st_bit[int(binary_list[i][0])] += 1

And you can make the same change across all the counter variables:

counter_1st_bit[int(binary_list[i][0])] += 1
counter_2nd_bit[int(binary_list[i][1])] += 1
counter_3rd_bit[int(binary_list[i][2])] += 1
counter_4th_bit[int(binary_list[i][3])] += 1
:
counter_12th_bit[int(binary_list[i][11])] += 1

And then you realize that your counter_xxx_bit variables could be replaced by a list of 12 lists!

# at start:
counter = [[0,0] for _ in range(12)]

# in loop:
for j in range(0, len(binary_list[i]), 1):
    counter[j][int(binary_list[i][j])] += 1

(Note: The [... for ... in ...] syntax is called a list comprehension. It's a shorthand that allows specifying the contents of a list as a single expression. This is super-valuable in places where statements are not permitted, like argument defaults and lambda functions. And initializing list variables...)

You can probably see how to make similar changes to your gamma and epsilon computation functions.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Good answer, especially for its tight focus on using collections (lists, in this case) rather than a proliferation of individual variables. \$\endgroup\$
    – FMc
    Dec 5 '21 at 0:32
  • \$\begingroup\$ The for loop could be simplified further using enumerate, and I'm sure there's probably some way of doing the whole thing in one line without needing a separate initialization step. \$\endgroup\$
    – Yay295
    Dec 5 '21 at 6:44

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.