Home Backend Development Python Tutorial Matchstick compression

Matchstick compression

Nov 25, 2024 pm 03:56 PM

Matchstick compression

Weekly Challenge 296

Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: String Compression

Task

You are given a string of alphabetic characters, $chars.

Write a script to compress the string with run-length encoding, as shown in the examples.

A compressed unit can be either a single character or a count followed by a character.

BONUS: Write a decompression function.

My solution

Thanks to the power of regular expressions, this is a pretty straight forward task. Both Python and Perl allow the replacement value to be a function. Therefore I have a function called sc that will convert multiple letters into a number and the letter. For example if the input was aaa, it would return 3a.

def sc(match):
    m = match.group(0)
    return str(len(m)) + m[0]
Copy after login
Copy after login

Then it is a matter of calling this function as required.

def string_compress(s: str) -> str:
    return re.sub(r'(([a-z])+)', sc, s)
Copy after login
Copy after login

The decompress function (Python only) works in a similar fashion. It takes a pattern of a number followed by a letter and changes it to the letter repeated the specified number of occurrences.

def usc(match):
    m = match.group(0)
    return m[-1] * int (m[:-1])

def string_decompress(s: str) -> str:
    return re.sub(r'(\d+[a-z])', usc, s)
Copy after login
Copy after login

For execution from the command line, I use the argparse module to see if the --decompress option is specified.

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--decompress", help="decompress the input", action='store_true')
    parser.add_argument("str", help="the string to compress/decompress")
    args = parser.parse_args()

    if args.decompress:
        result = string_decompress(args.str)
    else:
        result = string_compress(args.str)
    print(result)
Copy after login

Examples

$ ./ch-1.py abbc
a2bc

$ ./ch-1.py aaabccc
3ab3c

$ ./ch-1.py abcc
ab2c

$ ./ch-1.py --decompress a2bc
abbc

$ ./ch-1.py --decompress 3ab3c
aaabccc

$ ./ch-1.py --decompress ab2c
abcc
Copy after login

Task 2: Matchstick Square

Task

You are given an array of integers, @ints.

Write a script to find if it is possible to make one square using the sticks as in the given array @ints where $ints[ì] is the length of i-th stick.

My solution

This is going to be a little long, so strap yourself in. The first thing I check is the sum of the sticks is divisible by four. If it isn't, there is no possible solution and I can return false

I can also check that no single stick is longer than one side. If this occurs, I also return false.

With these two checks, all the examples would give the correct result. However, it would erroneously report that 4 3 3 3 3 is true when in fact it is not.

Attempt two

Looking at the examples and my own thinking, I thought the solution would be to match a pair of values to match each side. So for the example 3 4 1 4 3 1 we have two pairs of 3 and 1 sticks that makes four. This would solve the 4 3 3 3 3 issue, because three doesn't have a matching one.

But this wouldn't work if the sticks were 4 4 3 1 2 1 1, as one side uses three sticks (one 2 and two 1s)

Attempt three

So my next attempt was a little more complicated, and I thought was a good solution ... until it wasn't. For this attempt, I started with the longest stick. If it wasn't the length of the side, I then took the next longest stick required to complete the side, and repeated until there was no possible solution. Using this method the following solutions were true.

  • 4 4 3 1 2 1 1
  • 9 5 4 3 3 3 3 3 3
  • 9 6 3 5 4 3 3 3
  • 9 6 3 5 4 3 3 2 1

I thought this was the solution, until I realised that 9 5 3 1 5 2 2 3 3 3 would not work. First side is 9, next side is 5 3 1, and the third side would fail with 5 3 and no 1.

Attempt four

At this point, I started to wonder if it was even possible to come up with a solution that didn't involve brute force. So I slept on it, scribbled down lots of things in on my tablet (I'm on holiday so can't use my white board), and slept on it again. My conclusion is that using a recursive function is the only solution.

Maybe I'm just overthinking all of this, or maybe there is a real simple solution that I just have thought of (as was the case last week).

The final code

Still reading? Well done :)

For this task, I have a recursive function called make_side. It takes a list (arrayref in Perl) of sticks remaining, and the length required. It then goes though the remaining sticks (highest first). Then one of three things happen:

  • If the stick is longer than the required length, I skip it.
  • If it is the required length, I return it.
  • If it is short, I use it and call the function again to use another stick. The call removes the used stick, and reduces the required length by the length of the used stick.

The function will return a list of the sticks used, or None (undef in Perl) if no valid combination of sticks is found.

def sc(match):
    m = match.group(0)
    return str(len(m)) + m[0]
Copy after login
Copy after login

The final piece of the puzzle, I perform the checks mentioned in the first part (sum is divisible by four, no stick longer than a side), and then call the above function. If that returns None, I return false. If all the sticks are used, I return true.

def string_compress(s: str) -> str:
    return re.sub(r'(([a-z])+)', sc, s)
Copy after login
Copy after login

Examples

def usc(match):
    m = match.group(0)
    return m[-1] * int (m[:-1])

def string_decompress(s: str) -> str:
    return re.sub(r'(\d+[a-z])', usc, s)
Copy after login
Copy after login

The above is the detailed content of Matchstick compression. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1672
14
PHP Tutorial
1277
29
C# Tutorial
1257
24
Python vs. C  : Learning Curves and Ease of Use Python vs. C : Learning Curves and Ease of Use Apr 19, 2025 am 12:20 AM

Python is easier to learn and use, while C is more powerful but complex. 1. Python syntax is concise and suitable for beginners. Dynamic typing and automatic memory management make it easy to use, but may cause runtime errors. 2.C provides low-level control and advanced features, suitable for high-performance applications, but has a high learning threshold and requires manual memory and type safety management.

Learning Python: Is 2 Hours of Daily Study Sufficient? Learning Python: Is 2 Hours of Daily Study Sufficient? Apr 18, 2025 am 12:22 AM

Is it enough to learn Python for two hours a day? It depends on your goals and learning methods. 1) Develop a clear learning plan, 2) Select appropriate learning resources and methods, 3) Practice and review and consolidate hands-on practice and review and consolidate, and you can gradually master the basic knowledge and advanced functions of Python during this period.

Python vs. C  : Exploring Performance and Efficiency Python vs. C : Exploring Performance and Efficiency Apr 18, 2025 am 12:20 AM

Python is better than C in development efficiency, but C is higher in execution performance. 1. Python's concise syntax and rich libraries improve development efficiency. 2.C's compilation-type characteristics and hardware control improve execution performance. When making a choice, you need to weigh the development speed and execution efficiency based on project needs.

Python vs. C  : Understanding the Key Differences Python vs. C : Understanding the Key Differences Apr 21, 2025 am 12:18 AM

Python and C each have their own advantages, and the choice should be based on project requirements. 1) Python is suitable for rapid development and data processing due to its concise syntax and dynamic typing. 2)C is suitable for high performance and system programming due to its static typing and manual memory management.

Which is part of the Python standard library: lists or arrays? Which is part of the Python standard library: lists or arrays? Apr 27, 2025 am 12:03 AM

Pythonlistsarepartofthestandardlibrary,whilearraysarenot.Listsarebuilt-in,versatile,andusedforstoringcollections,whereasarraysareprovidedbythearraymoduleandlesscommonlyusedduetolimitedfunctionality.

Python: Automation, Scripting, and Task Management Python: Automation, Scripting, and Task Management Apr 16, 2025 am 12:14 AM

Python excels in automation, scripting, and task management. 1) Automation: File backup is realized through standard libraries such as os and shutil. 2) Script writing: Use the psutil library to monitor system resources. 3) Task management: Use the schedule library to schedule tasks. Python's ease of use and rich library support makes it the preferred tool in these areas.

Python for Scientific Computing: A Detailed Look Python for Scientific Computing: A Detailed Look Apr 19, 2025 am 12:15 AM

Python's applications in scientific computing include data analysis, machine learning, numerical simulation and visualization. 1.Numpy provides efficient multi-dimensional arrays and mathematical functions. 2. SciPy extends Numpy functionality and provides optimization and linear algebra tools. 3. Pandas is used for data processing and analysis. 4.Matplotlib is used to generate various graphs and visual results.

Python for Web Development: Key Applications Python for Web Development: Key Applications Apr 18, 2025 am 12:20 AM

Key applications of Python in web development include the use of Django and Flask frameworks, API development, data analysis and visualization, machine learning and AI, and performance optimization. 1. Django and Flask framework: Django is suitable for rapid development of complex applications, and Flask is suitable for small or highly customized projects. 2. API development: Use Flask or DjangoRESTFramework to build RESTfulAPI. 3. Data analysis and visualization: Use Python to process data and display it through the web interface. 4. Machine Learning and AI: Python is used to build intelligent web applications. 5. Performance optimization: optimized through asynchronous programming, caching and code

See all articles