Ad
Arrays
Sorting

Goal

Write a function that takes an array, and an integer as arguments. Your function should return a sub-array of the given array sorted by longest word -> shortest word. The returned array should be the first n elements where n is the given integer.

You should consider only letters for your sorting. Any other unicode character should be removed before comparison. If there are any empty strings because of this, remove them from the final list. If there are multiple words of the same length, maintain order of appearance. If you encounter a case where the number is longer than the array, or if the array is completely full of invalid words, return a string with the message: 'Invalid Parameters.'

Assume that each element of the array is a string that should be counted as one word.

Examples

INPUT: (["Hello", "world", "Coding", "is", "fun!"], 1) 
OUTPUT: ['Coding']

INPUT: (["Python", "Java", "C++", "JavaScript"], 4)
OUTPUT: ['JavaScript', 'Python', 'Java', 'C']

INPUT: (["Hello", "world", "Coding", "is", "fun!"], 6)
OUTPUT: 'Invalid Parameters'

Code
Diff
  • def longest_words(array, num):
        new = [k for k in sorted([''.join([i for i in j if 97 <= ord(i) <= 122 or 65 <= ord(i) <= 90]) for j in array], key=lambda x: len(x), reverse=True) if k != ''] 
        return new[:num] if num <= len(new) else 'Invalid Parameters'
    • longest_words(["Hello", "world", "Coding", "is", "fun!"])
    • # Output: ["Hello", "world", "Coding"]
    • longest_words(["Python", "Java", "C++", "JavaScript"])
    • # Output: ["Python", "JavaScript"]
    • def longest_words(array, num):
    • new = [k for k in sorted([''.join([i for i in j if 97 <= ord(i) <= 122 or 65 <= ord(i) <= 90]) for j in array], key=lambda x: len(x), reverse=True) if k != '']
    • return new[:num] if num <= len(new) else 'Invalid Parameters'
Strings
Cryptography

Goal

Code a function, ceasar that takes two arguments: string and position.

Your task is to shift all letters by pos. pos will always be an integer such that:

-25 >= pos <= 25

Examples

def ceasar('Az 2', 1): will output  ->  'Ba 2'

def ceasar('Az 2', -1): will output  ->  'Zy 2'

As shown above, if a character is not a letter, you should keep it as it is.

Fork 1

I improved your initial solution by using indexing instead of unicode math. You did make me think that there would be an interesting application to make a ceaser cypher that shifts characters by their unicode representation and not just their order in the alphabet.

I also added random testing that ended up being way overkill. In case you're curious how it works, I had ChatGPT write me 5 different sentences about programming, and then took each sentence.split() and created 3 lists. list one is the regular word with no substitutions, list two is the word with all substitutions, and list 3 is the word with some, but not all substitutions. The final list is just those three lists zipped together.

Code
Diff
  • def ceasar(string, pos):
        bet = 'abcdefghijklmnopqrstuvwxyz'
        new = bet[pos:] + bet[:pos]
        word = ''
        for char in string:
            if char.lower() in bet: word += new[bet.index(char.lower())].upper() if char.isupper() else new[bet.index(char)]
            else: word += char
        return word
    • def ceasar(string,pos):
    • ans = ""
    • if pos<0:
    • pos=26+pos%26
    • for ch in string:
    • if ch.isupper():
    • ans += chr((ord(ch) + pos-65) % 26 + 65)
    • elif ch.islower():
    • ans += chr((ord(ch) + pos-97) % 26 + 97)
    • else: ans+=ch
    • return ans
    • def ceasar(string, pos):
    • bet = 'abcdefghijklmnopqrstuvwxyz'
    • new = bet[pos:] + bet[:pos]
    • word = ''
    • for char in string:
    • if char.lower() in bet: word += new[bet.index(char.lower())].upper() if char.isupper() else new[bet.index(char)]
    • else: word += char
    • return word
Strings

Goal

Get dice roll results from multiple dice of the same type.

Dice notation

Dice are entered as strings such as "2d6" where the first number indicates the quantity of dice thrown and the last number indicates the number of sides on the dice. Assume input is "XdN" where 1 <= X <= 250 and <= N <= 5000

e.g. "2d6" means 2 dice are thrown. Each dice is a 6 sided dice with values 1-6.
2d6 should have results such as [2,5] or [1,6] or [3,3]

e.g. 3d500 (after setting random.seed(444) should result in [159,148,7]

Fork 1

Solved the problem, and added random testing. Currently the random tests will use any dice noted here and then each multiple of 50 above that.Calculating which number

Code
Diff
  • import random
    def roll_dice(dice):
        return [random.randint(1, int(dice[dice.index('d') + 1:])) for _ in range(int(dice[:dice.index('d')]))]
    
    • import random
    • def roll_dice(dice_text:str):
    • #this returns the correct value for roll_dice("2d1000")
    • return [random.randint(1,1000), random.randint(1,1000)]
    • def roll_dice(dice):
    • return [random.randint(1, int(dice[dice.index('d') + 1:])) for _ in range(int(dice[:dice.index('d')]))]

Goal

write a function that will return the integer of a string evaluation. Your function should catch any errors related to this process. If it does catch and error, it should return a string: "Invalid Input"

Fork 1

Added testing, and error checking. I think random tests should cover all realistic inputs that don't try to intentionally break the function. For example, KeyError would be pretty easy to create here, but why would you put something as complicated as a dictionary into this function without already knowing the keys?

Code
Diff
  • def calc(string):
        try: return int(eval(string))
        except (NameError, SyntaxError, TypeError, ValueError, ZeroDivisionError) as e:
            print(e)
            return 'Invalid Input'
    
    • def calc(string):
    • return int(eval(string))
    • try: return int(eval(string))
    • except (NameError, SyntaxError, TypeError, ValueError, ZeroDivisionError) as e:
    • print(e)
    • return 'Invalid Input'
Puzzles

Story

The pandemic has spread to all countries of the world, and Berland is no exception. Even at the All-Berland Olympiad in Computer Science, antiviral measures were introduced. In total, n people participate in the Olympiad, and in order to comply with all the instructions of the management, the Olympiad jury decided to invite participants to the tour one at a time with an interval of x minutes. Thus, the first participant will start the tour at time 0, the second participant will start the tour at time x, the third — at time 2x and so on.
Despite the different start times, the duration of the tour for each participant is exactly t minutes. Because of this, some participants finish writing the tour before the rest. When a participant finishes writing a tour, the amount of dissatisfaction with the organization of the Olympiad for this participant is equal to the number of other participants who are currently still writing or just starting to write a tour, but have not finished it yet.

Goal

Help the organizers of the Olympiad to find out what the total dissatisfaction of all participants of the Olympiad is equal to.

Input:

A single integer n is entered in the first line 1<=n<=2 * 10^9 — the number of participants of the Olympiad.
A single integer x is entered in the second line 1<=x<=2 * 10^9 — the interval in minutes between the start times of the tour for participants.
In the third line, a single integer t is entered 1<=t<=2 * 10^9 — duration of the tour.

Output:

In a single line, return one number — the total dissatisfaction of all participants of the Olympiad.

Examples

def satisfaction(4, 2, 5)  -->  5

def satisfaction(3, 1, 2)  -->  3

def satisfaction(3, 3, 10)  -->  3

  • In the first example , the first participant will start writing the tour at time 0 and finish at time 5. By this time, the second and third participants will already start writing the tour, so the dissatisfaction of the first participant will be equal to 2. The second participant will start writing at time 2 and finish at time 7. By this point, the third and fourth participants will already start writing the tour, so the dissatisfaction of the second will be equal to 2. The third participant will start writing the tour at time 4 and finish at time 9. By this time, the fourth participant will already start writing the tour, so the dissatisfaction of the third will be equal to 1. The fourth participant will start writing the tour at time 6 and finish at time 11. At time 9 no one will write a tour anymore, so the dissatisfaction of the fourth will be equal to 0. Thus, the total dissatisfaction of all participants will be equal to 2+2+1+0=5.

  • In the second example , the first participant will start writing the tour at time 0 and finish at time 2. By this point, the second participant will already be writing the tour, and the third participant will just start at time 2. Therefore , the dissatisfaction of the first participant will be equal to 2. The second participant will start at time 1and finish at time 3. By this point, only the third participant will still be writing the tour. Thus, the total dissatisfaction of all participants will be equal to 2+1=3.

Fork 1

I think I met the bid here. I wrote some edge cases that you should check to make sure that they follow the rules as well, but I've been treating all comparisons as <= since you said:

currently still writing or just starting to write a tour, but have not finished it yet.

Either way, really fun challenge! If this is looking good for you, just add some random tests and this will be ready for a kata IMO. This was a really fun puzzle to figure out because it's not just math that helps you get to the right solution, but clever coding logic as well. This would be a really fun kata when you're satisfied... get it?

Code
Diff
  • def satisfaction(n, x, t):
        start_times = [i * x for i in range(n)]
        finish_times = [(i * x) + t for i in range(n)]
        upset_factor = 0
        
        for i, writer in enumerate(finish_times):
            for j, others in enumerate(start_times):
                if others <= writer and i < j:
                    upset_factor += 1
        print(start_times, finish_times)
        return upset_factor
    
    • def qwerty(n, x, t):
    • time_finish_before_start = t + x * (n - 1)
    • time_start_before_finish = t + x * (n - 2)
    • dissatisfaction_finish_before_start = min(n - 1, time_finish_before_start // x)
    • dissatisfaction_start_before_finish = max(0, n - 2 - dissatisfaction_finish_before_start)
    • total_dissatisfaction = dissatisfaction_finish_before_start * dissatisfaction_start_before_finish
    • return total_dissatisfaction
    • def satisfaction(n, x, t):
    • start_times = [i * x for i in range(n)]
    • finish_times = [(i * x) + t for i in range(n)]
    • upset_factor = 0
    • for i, writer in enumerate(finish_times):
    • for j, others in enumerate(start_times):
    • if others <= writer and i < j:
    • upset_factor += 1
    • print(start_times, finish_times)
    • return upset_factor
p4songervs.EPiphFailed Tests

Bonk

Probability
Statistics

Goal

Not really sure. But it looks like we're calculating the actual probability of a ruleset and comparing it to the calculated probability.

Fork 1

I changed the testing to use assert_approx_equals instead of assert_equals since the implementation was the same, and it makes testing more consistent. Added a zero to the range we're using to increase the odds we will match expected probability, and made a minor optimization to use a comprehension since we're iterating 100,000 times.

I also refactored the funtion to take our alternate ruleset, and run those rules if true. Can't get it to pass the tests though. It's something though.

Code
Diff
  • from random import randint
    
    
    playing_board = [0] * 100 # board is 100 positions long
    position = 0 # player starts at position 0 on the board
    while position < 100: # end when position moves off board
        playing_board[position] = 1 # player was here
        position += randint(1, 6) # throw a die and move
    
    # what's the probability that playing_board[n] == 1?
    # there is a prize if you land on position n
    # but a cost for playing the game
    # let's run N times
    
    def probability(other_rule=False):
        successes = [0] * 100
        if not other_rule:
            for n in range(100000): # maybe this isn't big enough # maybe it is now?
                playing_board = [0] * 100
                position = 0
                while position < 100:
                    successes[position] += 1
                    position += randint(1, 6)
            return [s / n for s in successes]
        
        # what if we add a rule
        # if the player lands on square 99, they teleport back to 0
        for n in range(100000):
            playing_board = [0] * 100 # board is 100 positions long
            position = 0 # player starts at position 0 on the board
            while position < 100: # end when position moves off board
                successes[position] += 1 # player was here
                position += randint(1, 6) # throw a die and move
                if position == 99: position = 0 # snakey snake
        return [s / n for s in successes]
        
    
    
    
    # can you calculate the probability of the prize now?
    • from random import randint
    • playing_board = [0] * 100 # board is 100 positions long
    • position = 0 # player starts at position 0 on the board
    • while position < 100: # end when position moves off board
    • playing_board[position] = 1 # player was here
    • position += randint(1, 6) # throw a die and move
    • # what's the probability that playing_board[n] == 1?
    • # there is a prize if you land on position n
    • # but a cost for playing the game
    • # let's run N times
    • def probability():
    • N = 10000 # maybe this isn't big enough
    • def probability(other_rule=False):
    • successes = [0] * 100
    • for _ in range(N):
    • playing_board = [0] * 100
    • position = 0
    • while position < 100:
    • successes[position] += 1
    • position += randint(1, 6)
    • ret = []
    • for s in successes:
    • ret.append(s / N)
    • return ret
    • if not other_rule:
    • for n in range(100000): # maybe this isn't big enough # maybe it is now?
    • playing_board = [0] * 100
    • position = 0
    • while position < 100:
    • successes[position] += 1
    • position += randint(1, 6)
    • return [s / n for s in successes]
    • # what if we add a rule
    • # if the player lands on square 99, they teleport back to 0
    • for n in range(100000):
    • playing_board = [0] * 100 # board is 100 positions long
    • position = 0 # player starts at position 0 on the board
    • while position < 100: # end when position moves off board
    • successes[position] += 1 # player was here
    • position += randint(1, 6) # throw a die and move
    • if position == 99: position = 0 # snakey snake
    • return [s / n for s in successes]
    • # what if we add a rule
    • # if the player lands on square 99, they teleport back to 0
    • playing_board = [0] * 100 # board is 100 positions long
    • position = 0 # player starts at position 0 on the board
    • while position < 100: # end when position moves off board
    • playing_board[position] = 1 # player was here
    • position += randint(1, 6) # throw a die and move
    • if position == 99: position = 0 # snakey snake
    • # can you calculate the probability of the prize now?
Matrix

Goal

Write a function matrix() that takes a 2D array, an operation, a target location, and an optional write_data as an input.

def matrix(matrice=[[1,2,3],
                    [4,5,6],
                    [7,8,9]], operation="write", location=(0, 1), write_data=7)

Your function should catch any IndexError that occers. Return values should be:

  • if write: The new matrix, after adding write_data in the location given.
  • if read: The existing data at the requested location.
  • if neither: raise an AttributeError with any message.

Fork 1

Cleaned up some of the error checking to use best practices. Added testing for the error checking. Added random testing with basic matricies from numpy.

The random tests are honestly scuffed beyond belief. I've never worked with numpy before, and this is probably a bad first experience. I would love to see someone fix the mess that I've made lol... sorry in advance. I decided to cap the size of random tests at 100 since this isn't really meant to be a preformance type kumite. Ran a couple times and seems like a good upper limit imo.

Code
Diff
  • def matrix(matrice=list, operation=str, location=tuple, write_data=None):
        if operation == "read":
            try: 
                return matrice[location[0]][location[1]]
            except IndexError as e:
                print(e)
                return 0
        elif operation == "write":
            try:
                matrice[location[0]][location[1]] = write_data
                return matrice
            except IndexError as e:
                print(e)
                return 0
        else:
            raise AttributeError("That is not a valid operation for this system.")
    • def matrix(matrice=list, operation=str, location=tuple, writedata=None):
    • def matrix(matrice=list, operation=str, location=tuple, write_data=None):
    • if operation == "read":
    • try:
    • try:
    • return matrice[location[0]][location[1]]
    • except Exception as e:
    • except IndexError as e:
    • print(e)
    • return 0
    • elif operation == "write":
    • try:
    • matrice[location[0]][location[1]] = writedata
    • matrice[location[0]][location[1]] = write_data
    • return matrice
    • except Exception as e:
    • except IndexError as e:
    • print(e)
    • return 0
    • else:
    • raise OperationError("That is not a valid operation for this system.")
    • raise AttributeError("That is not a valid operation for this system.")

Goal

You are collecting data that fits a wave signal. Your must determine witch mathematical expression fits the signal. You will receive an array of numbers into your function called find_signal()

All numbers in the array will obey one of these expressions:
y = sin x,
y = cos x,
y = sin x + cos x

The given y values will always correspond to x input values of 0, 1, 2, ... n where n is the length of the array - 1. Your function will identify which signal is coming in and return string: 'sin x', 'cos x' or 'sin x + cos x'. Otherwise, None

All inputs will have at least 2 numbers to indicate a clear answer.

Fork 1

Removed duplicate tests. Added more precise floating point values instead of rounded numbers. (I think its best practice to avoid rounding where it is not absolutely necessary? Either way, it makes the random tests easier to build, and the actual code more accurate). Added random tests

In addition to what's above, I refactored pretty much the whole code to accept more than just 4 numbers. The random tests will give an array of size 2 <= n <= 1000. We start at 2 to avoid edge cases between cos, and sin + cos. I'm sure someone smarter than I could find a way to include those as well, but I think this is good enough for a pretty simple problem like this.

Code
Diff
  • import math as m
    def find_signal(wave): 
        sinx = ('sin x', [i for i in range(len(wave)) if wave[i] == m.sin(i)])
        cosx = ('cos x', [i for i in range(len(wave)) if wave[i] == m.cos(i)])
        cossin = ('sin x + cos x', [i for i in range(len(wave)) if wave[i] == m.cos(i) + m.sin(i)])
        final = max([sinx, cosx, cossin], key=lambda x : sum(x[1]))
        return final[0] if sum(final[1]) == sum([i for i in range(len(wave))]) else None
    
            
    • import math as m
    • def find_signal(s):
    • k=0; k1=0; k2=0
    • for i in range(4):
    • if s[i]==round(m.sin(i),2):
    • k=k+1
    • if k==4:
    • return('sin x')
    • if s[i]==round(m.cos(i),2):
    • k1=k1+1
    • if k1==4:
    • return('cos x')
    • if s[i]==round(m.cos(i)+m.sin(i),2):
    • k2=k2+1
    • if k2==4:
    • return('sin x + cos x')
    • def find_signal(wave):
    • sinx = ('sin x', [i for i in range(len(wave)) if wave[i] == m.sin(i)])
    • cosx = ('cos x', [i for i in range(len(wave)) if wave[i] == m.cos(i)])
    • cossin = ('sin x + cos x', [i for i in range(len(wave)) if wave[i] == m.cos(i) + m.sin(i)])
    • final = max([sinx, cosx, cossin], key=lambda x : sum(x[1]))
    • return final[0] if sum(final[1]) == sum([i for i in range(len(wave))]) else None

GOAL:

write a class that will greet a person when called.

Code
Diff
  • class Greeting:
        def __init__(self, name, rank=None, formal=False):
            self.name = name
            self.rank = rank
            self.formal = formal
            
        def __call__(self):
            if self.formal: return f'Hello,{" " + self.rank if self.rank is not None else ""} {self.name}.'
            else: return f'Hey, {self.name}!'
        
    • class greeting:
    • def __init__(self, name: str, formal: bool = False):
    • class Greeting:
    • def __init__(self, name, rank=None, formal=False):
    • self.name = name
    • self.rank = rank
    • self.formal = formal
    • def __call__(self) -> str:
    • if self.formal: return f'Hello, Sir {self.name}.'
    • else: return f'Hello, {self.name}!'
    • g1 = greeting('John')
    • g2 = greeting('Churchill', True)
    • print(g1()) # 'Hello, John!'
    • print(g2()) # 'Hello, Sir Churchill.'
    • def __call__(self):
    • if self.formal: return f'Hello,{" " + self.rank if self.rank is not None else ""} {self.name}.'
    • else: return f'Hey, {self.name}!'

Description:

The grid is a rectangular matrix consisting of non-negative integers representing the cost of moving to a specific cell. Each cell in the grid corresponds to a position in the path, and the value of the cell represents the cost associated with taking a step to that position.

Goal:

Move from position grid[0][0] to position grid[-1][-1] with as little cost as possible.

Allowed Moves:

You can only move horizontally (left or right) or vertically (up or down) to adjacent cells. Diagonal moves are not allowed

Additional Logic:

If there is uncertainty for which direction to go, AKA a tie, prioritize moving right. If you cannot move right, move down.

Examples:

Input:
[[0, 5, 4, 3],
 [1, 0, 0, 0],
 [2, 6, 7, 0]]

Logic:
(0,0) -> (1,0) -> (1,1) -> (1,2) -> (1,3) -> (2,3)

Output: 
(0 + 1 + 0 + 0 + 0 + 0) = 1

Input (Edge case):
[[0, 9, 0, 0, 0],
 [0, 9, 0, 9, 0],
 [0, 0, 0, 9, 0]]
 
Logic:
(0,0) -> (1,0) -> (2,0) -> (2,1) -> (2,2) -> (1,2) -> (0,2) -> (0,3) ...
...   -> (0,4) -> (1,4) -> (2,4)

Output: 
0 (no values higher than zero collected on this path)

Fork #1:

Based off of the description you made, you left a couple of edge cases. Mainly that you never clarified that up or left are invalid. It could be assumed by the way your code ran, but it wasn't clear. I covered three of those edge cases here, but I left edge case 4 as a failed test just because my brain already hurts too much to add depth to the algorithm. Either way, this was a fun challenge! If no one makes improvements on this in a few days, I'll refactor again and write random tests for this.

Code
Diff
  • def kimite(grid):
        rows, cols = len(grid), len(grid[0])
        position = (0, 0)
        seen = set()
        total_cost = 0
    
        # Helper function to find the min cost based on current coordinates
        def get_step_cost(*directions, ):
            compare = sorted([i for i in directions if i != None], key=lambda x: x[0])
            multiple = [x for x in [i for i in directions if i != None] if x[0] == compare[0][0]]
            if len(multiple) > 1:
                for i in multiple:
                    if i[1] == 'right':
                        return i
                for i in multiple:
                    if i[1] == 'down':
                        return i
            else:
                return compare[0]
    
        # Helper function to find polar directions
        def get_direction():
            up, down, left, right = None, None, None, None
            # Check Y
            if position[0] > 0 and (position[0] - 1, position[1]) not in seen:
                up = (grid[position[0] - 1][position[1]], 'up')
            if position[0] + 1 < rows and (position[0] + 1, position[1]) not in seen:
                down = (grid[position[0] + 1][position[1]], 'down')
            # Check X
            if position[1] > 0 and (position[0], position[1] - 1) not in seen:
                left = (grid[position[0]][position[1] - 1], 'left')
            if position[1] + 1 < cols and (position[0], position[1] + 1) not in seen:
                right = (grid[position[0]][position[1] + 1], 'right')
            return (up, down, left, right)
    
        # Traverse the grid to find the minimum cost path
        while position != (rows - 1, cols - 1):
            direction = get_direction()
            cost, move = get_step_cost(*direction)
            if move == 'up': 
                position = (position[0] - 1, position[1])
                total_cost += cost
                seen.add(position)
                continue
    
            if move == 'down':
                position = (position[0] + 1, position[1])
                total_cost += cost
                seen.add(position)
                continue
    
            if move == 'left':
                position = (position[0], position[1] - 1)
                total_cost += cost
                seen.add(position)
                continue
    
            if move == 'right':
                position = (position[0], position[1] + 1)
                total_cost += cost
                seen.add(position)
    
        return total_cost
    
    
    
    • def kimite(grid):
    • rows = len(grid)
    • cols = len(grid[0])
    • # Helper function to calculate the cost of a step based on current coordinates and direction
    • def get_step_cost(x, y, direction):
    • if direction == "right" and x + 1 < cols:
    • return grid[y][x + 1]
    • elif direction == "down" and y + 1 < rows:
    • return grid[y + 1][x]
    • rows, cols = len(grid), len(grid[0])
    • position = (0, 0)
    • seen = set()
    • total_cost = 0
    • # Helper function to find the min cost based on current coordinates
    • def get_step_cost(*directions, ):
    • compare = sorted([i for i in directions if i != None], key=lambda x: x[0])
    • multiple = [x for x in [i for i in directions if i != None] if x[0] == compare[0][0]]
    • if len(multiple) > 1:
    • for i in multiple:
    • if i[1] == 'right':
    • return i
    • for i in multiple:
    • if i[1] == 'down':
    • return i
    • else:
    • return float('inf') # Return a very high cost if the step is not allowed
    • return compare[0]
    • # Initialize a 2D list to keep track of the minimum cost to reach each cell
    • min_costs = [[float('inf')] * cols for _ in range(rows)]
    • min_costs[0][0] = grid[0][0]
    • # Helper function to find polar directions
    • def get_direction():
    • up, down, left, right = None, None, None, None
    • # Check Y
    • if position[0] > 0 and (position[0] - 1, position[1]) not in seen:
    • up = (grid[position[0] - 1][position[1]], 'up')
    • if position[0] + 1 < rows and (position[0] + 1, position[1]) not in seen:
    • down = (grid[position[0] + 1][position[1]], 'down')
    • # Check X
    • if position[1] > 0 and (position[0], position[1] - 1) not in seen:
    • left = (grid[position[0]][position[1] - 1], 'left')
    • if position[1] + 1 < cols and (position[0], position[1] + 1) not in seen:
    • right = (grid[position[0]][position[1] + 1], 'right')
    • return (up, down, left, right)
    • # Traverse the grid to find the minimum cost path
    • for y in range(rows):
    • for x in range(cols):
    • # Check rightward move
    • right_cost = min_costs[y][x] + get_step_cost(x, y, "right")
    • if x + 1 < cols and right_cost < min_costs[y][x + 1]:
    • min_costs[y][x + 1] = right_cost
    • # Check downward move
    • down_cost = min_costs[y][x] + get_step_cost(x, y, "down")
    • if y + 1 < rows and down_cost < min_costs[y + 1][x]:
    • min_costs[y + 1][x] = down_cost
    • # The minimum cost to reach the destination is stored at the bottom-right cell
    • destination_cost = min_costs[rows - 1][cols - 1]
    • return destination_cost if destination_cost != float('inf') else -1
    • # Test cases
    • grid1 = [[0, 5, 4, 3],
    • [1, 0, 0, 0],
    • [2, 6, 7, 0]]
    • print(kimite(grid1)) # Output: 12
    • grid2 = [[0, 2, 3, 4],
    • [5, 0, 0, 0],
    • [6, 7, 8, 0]]
    • print(kimite(grid2)) # Output: 9
    • grid3 = [[0, 1, 2, 3],
    • [6, 0, 4, 0],
    • [5, 9, 8, 0]]
    • print(kimite(grid3)) # Output: 6
    • while position != (rows - 1, cols - 1):
    • direction = get_direction()
    • cost, move = get_step_cost(*direction)
    • if move == 'up':
    • position = (position[0] - 1, position[1])
    • total_cost += cost
    • seen.add(position)
    • continue
    • if move == 'down':
    • position = (position[0] + 1, position[1])
    • total_cost += cost
    • seen.add(position)
    • continue
    • if move == 'left':
    • position = (position[0], position[1] - 1)
    • total_cost += cost
    • seen.add(position)
    • continue
    • if move == 'right':
    • position = (position[0], position[1] + 1)
    • total_cost += cost
    • seen.add(position)
    • return total_cost

Task:

You are given two words, begin_word and end_word, and an array of words, word_list. Your task is to find the shortest transformation sequence from begin_word to end_word, such that:

  • Only one letter can be changed at a time.
  • Each transformed word must exist in the given wordList.

Return the length of the shortest transformation sequence. If there is no such transformation sequence, return None.

Example:

Input:
begin_word = "hit"
end_word = "cog"
word_list = ["hot","dot","dog","lot","log","cog"]

Output: 5

Explanation: 
One shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
returning its length gives us 5.

Input Parameters:

All words have the same length.
All words contain only lowercase alphabetic characters.
You may assume no duplicates in the word_list.
You may assume begin_word and end_word are non-empty and are not the same.

Fork #1:

I re-wrote the variable names to use python naming conventions. Also added some random tests of various sizes, as well as clarifying some of the test names to be more detailed. (e.g. Test Case #1 -> Valid: hit -> cog). This will be helpful for debugging when made into a kata (which it looks pretty much ready for imo). I also just used a function instead of a class. Not sure why you would assign a class that only has one method, and doesn't need to keep track of instances, but like I said, it looks like you're used to different conventions where this is typical, or even the only way to use functions.

Have you also written this in a c-type language? That looks like the convention that you were using.

Code
Diff
  • def ladder_length(begin_word, end_word, word_list):
        if end_word not in word_list: return 0
    
        word_set = set(word_list)
        queue = {(begin_word, 1)}
        visited = set()
    
        while queue:
            word, level = queue.pop()
            if word == end_word: return level
    
            for i in range(len(word)):
                for char in 'abcdefghijklmnopqrstuvwxyz':
                    new_word = word[:i] + char + word[i+1:]
    
                    if new_word in word_set and new_word not in visited:
                        queue.add((new_word, level + 1))
                        visited.add(new_word)
        return 0
    
    • from collections import deque
    • def ladder_length(begin_word, end_word, word_list):
    • if end_word not in word_list: return 0
    • class Solution:
    • @staticmethod
    • def ladderLength(beginWord, endWord, wordList):
    • if endWord not in wordList:
    • return 0
    • wordSet = set(wordList)
    • queue = deque([(beginWord, 1)])
    • visited = set()
    • while queue:
    • word, level = queue.popleft()
    • if word == endWord:
    • return level
    • for i in range(len(word)):
    • for char in 'abcdefghijklmnopqrstuvwxyz':
    • newWord = word[:i] + char + word[i+1:]
    • if newWord in wordSet and newWord not in visited:
    • queue.append((newWord, level + 1))
    • visited.add(newWord)
    • return 0
    • word_set = set(word_list)
    • queue = {(begin_word, 1)}
    • visited = set()
    • while queue:
    • word, level = queue.pop()
    • if word == end_word: return level
    • for i in range(len(word)):
    • for char in 'abcdefghijklmnopqrstuvwxyz':
    • new_word = word[:i] + char + word[i+1:]
    • if new_word in word_set and new_word not in visited:
    • queue.add((new_word, level + 1))
    • visited.add(new_word)
    • return 0
Strings
Fundamentals

Hungarian notation is a variable naming convention that describes the type of variable within the first letter of the variable name. For more info click here. For example, if you have a variable equal to None, hungarian case would be to name this nVariable.

Write a function that will convert our variable names to use this convention. Assume that variable names are one word strings, and the value that the variable is holding is an actual value. Return a string that fits the format for the examples below:

Input: ('variable', None) -> 'nVariable'

Input: ('sTRING', ''), -> 'sString'

Input: ('Decimal', 1.0) -> 'fDecimal'

Note to others:

Not sure how much value this would have as a kata, but I think there's some potential here. I think its just not quite interesting enough. Let me know if there's some way to re-factor the challenge in a fun way!

FORK 1:

Figured out a more clever one-liner that doesn't import re.

Code
Diff
  • def hNotation(var, val):
        return f'{str(type(val))[8].lower()}{var.title()}'
        
    • import re
    • def hNotation(var, val):
    • char = re.match(r"<class '(\w)", str(type(val))).group(1).lower()
    • return f'{char}{var.title()}'
    • return f'{str(type(val))[8].lower()}{var.title()}'

Goal: Re-write this function as a lambda function:

def summ(*args):
    numbers = 0
    for x in args:
        numbers += x
    return numbers

Wrote tests that are assuming the input is a sequence of numbers.

Code
Diff
  • summ = lambda *x : sum([i for i in x])
    • def summ(*args):
    • numbers = 0
    • for x in args:
    • numbers += x
    • return numbers
    • summ = lambda *x : sum([i for i in x])

Write a function that returns the fibonacci sequence starting at 1, and ending at the first number greater than n inclusive, with the sum of the sequence as a tuple. Assume all inputs are positive integers.

Code
Diff
  • def fibthing(make=int):
        fibseq = []
        while max(fibseq, default=0) < make:
            if len(fibseq) > 1: 
                fibseq.append(fibseq[-1] + fibseq[-2])
            else: 
                fibseq.append(1)
        return fibseq, sum(fibseq)
    • def fibthing(make=int):
    • fibseq = []
    • n1 = 0
    • n2 = 1
    • cur = 0
    • sum = 0
    • while cur < make:
    • fibseq.append(n2)
    • cur = n2
    • n2 = n1 + cur
    • n1 = cur
    • for i in fibseq:
    • sum += i
    • return fibseq, sum
    • while max(fibseq, default=0) < make:
    • if len(fibseq) > 1:
    • fibseq.append(fibseq[-1] + fibseq[-2])
    • else:
    • fibseq.append(1)
    • return fibseq, sum(fibseq)

Goal: You have to print the string n times if a is True.

(added some tests, and a working function for the previous task you described. Not exactly sure what the goal is, so I just had it return the string + newline for n lines.)

Code
Diff
  • def print_n(string, n, a):
        if isinstance(a, bool) and a is True:
            for _ in range(n): print(string)
            return '\n'.join([string for _ in range(n)])
        return None
    • a = True
    • if a == True:print("hi")
    • def print_n(string, n, a):
    • if isinstance(a, bool) and a is True:
    • for _ in range(n): print(string)
    • return '\n'.join([string for _ in range(n)])
    • return None
Loading more items...