diff options
| -rw-r--r-- | challenge-165/paulo-custodio/ch-2.svg | 2 | ||||
| -rw-r--r-- | challenge-165/paulo-custodio/perl/ch-1.pl | 10 | ||||
| -rw-r--r-- | challenge-165/paulo-custodio/perl/ch-2.pl | 4 | ||||
| -rw-r--r-- | challenge-165/paulo-custodio/python/ch-1.py | 71 | ||||
| -rw-r--r-- | challenge-165/paulo-custodio/python/ch-2.py | 75 | ||||
| -rw-r--r-- | challenge-166/paulo-custodio/perl/ch-1.pl | 10 | ||||
| -rw-r--r-- | challenge-166/paulo-custodio/perl/ch-2.pl | 2 | ||||
| -rw-r--r-- | challenge-166/paulo-custodio/python/ch-1.py | 45 | ||||
| -rw-r--r-- | challenge-166/paulo-custodio/python/ch-2.py | 83 | ||||
| -rw-r--r-- | challenge-166/paulo-custodio/t/dir_a/Old_Fonts/.keep | 0 |
10 files changed, 289 insertions, 13 deletions
diff --git a/challenge-165/paulo-custodio/ch-2.svg b/challenge-165/paulo-custodio/ch-2.svg index 32091d0113..4e115403f6 100644 --- a/challenge-165/paulo-custodio/ch-2.svg +++ b/challenge-165/paulo-custodio/ch-2.svg @@ -49,5 +49,5 @@ <circle cx="189" cy="154" r="1" stroke="black" /> <circle cx="361" cy="82" r="1" stroke="black" /> <circle cx="363" cy="89" r="1" stroke="black" /> -<line x1="0" y1="200.132272535582" x2="500" y2="50.1540224049662" stroke="black" /> +<line x1="0" y1="200" x2="500" y2="50" stroke="black" /> </svg> diff --git a/challenge-165/paulo-custodio/perl/ch-1.pl b/challenge-165/paulo-custodio/perl/ch-1.pl index 116422d124..e35a965a7e 100644 --- a/challenge-165/paulo-custodio/perl/ch-1.pl +++ b/challenge-165/paulo-custodio/perl/ch-1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Challenge 165 # @@ -7,13 +7,13 @@ # # Scalable Vector Graphics (SVG) are not made of pixels, but lines, ellipses, # and curves, that can be scaled to any size without any loss of quality. If you -# have ever tried to resize a small JPG or PNG, you know what I mean by “loss of -# quality”! What many people do not know about SVG files is, they are simply XML +# have ever tried to resize a small JPG or PNG, you know what I mean by "loss of +# quality"! What many people do not know about SVG files is, they are simply XML # files, so they can easily be generated programmatically. # -# For this task, you may use external library, such as Perl’s SVG library, +# For this task, you may use external library, such as Perl's SVG library, # maintained in recent years by our very own Mohammad S Anwar. You can instead -# generate the XML yourself; it’s actually quite simple. The source for the +# generate the XML yourself; it's actually quite simple. The source for the # example image for Task #2 might be instructive. # # Your task is to accept a series of points and lines in the following format, diff --git a/challenge-165/paulo-custodio/perl/ch-2.pl b/challenge-165/paulo-custodio/perl/ch-2.pl index df2d904645..160b7f1a77 100644 --- a/challenge-165/paulo-custodio/perl/ch-2.pl +++ b/challenge-165/paulo-custodio/perl/ch-2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Challenge 165 # @@ -44,6 +44,7 @@ END sub svg_circle { my($cx, $cy, $r)=@_; + for($cx, $cy, $r) {$_=int($_);} return <<END; <circle cx="$cx" cy="$cy" r="$r" stroke="black" /> END @@ -56,6 +57,7 @@ sub svg_point { sub svg_line { my($x1,$y1,$x2,$y2)=@_; + for($x1,$y1,$x2,$y2) {$_=int($_);} return <<END; <line x1="$x1" y1="$y1" x2="$x2" y2="$y2" stroke="black" /> END diff --git a/challenge-165/paulo-custodio/python/ch-1.py b/challenge-165/paulo-custodio/python/ch-1.py new file mode 100644 index 0000000000..523e15afe1 --- /dev/null +++ b/challenge-165/paulo-custodio/python/ch-1.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +# Challenge 165 +# +# Task 1: Scalable Vector Graphics (SVG) +# Submitted by: Ryan J Thompson +# +# Scalable Vector Graphics (SVG) are not made of pixels, but lines, ellipses, +# and curves, that can be scaled to any size without any loss of quality. If you +# have ever tried to resize a small JPG or PNG, you know what I mean by "loss of +# quality"! What many people do not know about SVG files is, they are simply XML +# files, so they can easily be generated programmatically. +# +# For this task, you may use external library, such as Perl's SVG library, +# maintained in recent years by our very own Mohammad S Anwar. You can instead +# generate the XML yourself; it's actually quite simple. The source for the +# example image for Task #2 might be instructive. +# +# Your task is to accept a series of points and lines in the following format, +# one per line, in arbitrary order: +# +# Point: x,y +# +# Line: x1,y1,x2,y2 +# Example: +# +# 53,10 +# 53,10,23,30 +# 23,30 +# +# Then, generate an SVG file plotting all points, and all lines. If done +# correctly, you can view the output .svg file in your browser. + +def svg_header(width, height): + return f'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="{height}" width="{width}" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +''' + +def svg_footer(): + return '''</svg> +''' + +def svg_circle(cx, cy, r): + return f'<circle cx="{cx}" cy="{cy}" r="{r}" stroke="black" />\n' + +def svg_point(cx, cy): + return svg_circle(cx, cy, 1) + +def svg_line(x1, y1, x2, y2): + return f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" stroke="black" />\n' + +import sys + +file = sys.argv[1] if len(sys.argv) > 1 else None +if file is None: + raise Exception("usage: ch-1.py file.svg") + +with open(file, "w") as f: + f.write(svg_header(100, 100)) + for line in sys.stdin: + line = line.strip() + p = line.split(',') + p = [int(coord.strip()) for coord in p] + if len(p) == 2: + f.write(svg_point(*p)) + elif len(p) == 4: + f.write(svg_line(*p)) + else: + raise Exception(f"cannot parse: {line}") + f.write(svg_footer()) diff --git a/challenge-165/paulo-custodio/python/ch-2.py b/challenge-165/paulo-custodio/python/ch-2.py new file mode 100644 index 0000000000..265da63b9f --- /dev/null +++ b/challenge-165/paulo-custodio/python/ch-2.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +# Challenge 165 +# +# Task 2: Line of Best Fit +# Submitted by: Ryan J Thompson +# +# When you have a scatter plot of points, a line of best fit is the line that +# best describes the relationship between the points, and is very useful in +# statistics. Otherwise known as linear regression, here is an example of what +# such a line might look like: +# +# Hull +# +# The method most often used is known as the least squares method, as it is +# straightforward and efficient, but you may use any method that generates the +# correct result. +# +# Calculate the line of best fit for the following 48 points: +# +# 333,129 39,189 140,156 292,134 393,52 160,166 362,122 13,193 +# 341,104 320,113 109,177 203,152 343,100 225,110 23,186 282,102 +# 284,98 205,133 297,114 292,126 339,112 327,79 253,136 61,169 +# 128,176 346,72 316,103 124,162 65,181 159,137 212,116 337,86 +# 215,136 153,137 390,104 100,180 76,188 77,181 69,195 92,186 +# 275,96 250,147 34,174 213,134 186,129 189,154 361,82 363,89 + +import sys + +def svg_header(width, height): + return f'''<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="{height}" width="{width}" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> +''' + +def svg_footer(): + return '''</svg> +''' + +def svg_circle(cx, cy, r): + return f'<circle cx="{int(cx)}" cy="{int(cy)}" r="{int(r)}" stroke="black" />\n' + +def svg_point(cx, cy): + return svg_circle(cx, cy, 1) + +def svg_line(x1, y1, x2, y2): + return f'<line x1="{int(x1)}" y1="{int(y1)}" x2="{int(x2)}" y2="{int(y2)}" stroke="black" />\n' + +def least_squares(points): + N = len(points) + sum_x = sum_y = sum_x2 = sum_xy = 0 + for x, y in points: + sum_x += x + sum_y += y + sum_x2 += x * x + sum_xy += x * y + m = (N * sum_xy - sum_x * sum_y) / (N * sum_x2 - sum_x * sum_x) + b = (sum_y - m * sum_x) / N + return m, b + +file = sys.argv[1] if len(sys.argv) > 1 else None +if file is None: + raise Exception("usage: ch-1.py file.svg") + +with open(file, "w") as f: + f.write(svg_header(500, 500)) + points = [] + for line in sys.stdin: + for point in line.split(): + x, y = map(int, point.split(',')) + points.append((x, y)) + f.write(svg_point(x, y)) + m, b = least_squares(points) + f.write(svg_line(0, b, 500, m * 500 + b)) + f.write(svg_footer()) diff --git a/challenge-166/paulo-custodio/perl/ch-1.pl b/challenge-166/paulo-custodio/perl/ch-1.pl index 8e6f78001a..0764002300 100644 --- a/challenge-166/paulo-custodio/perl/ch-1.pl +++ b/challenge-166/paulo-custodio/perl/ch-1.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Challenge 166 # @@ -10,22 +10,22 @@ # 0xC0dedBad. I want more! # # Write a program that will read from a dictionary and find 2- to 8-letter -# words that can be “spelled” in hexadecimal, with the addition of the following +# words that can be "spelled" in hexadecimal, with the addition of the following # letter substitutions: # -# o -> 0 (e.g., 0xf00d = “food”) +# o -> 0 (e.g., 0xf00d = "food") # l -> 1 # i -> 1 # s -> 5 # t -> 7 # # You can use your own dictionary or you can simply open -# ../../../data/dictionary.txt (relative to your script’s location in our GitHub +# ../../../data/dictionary.txt (relative to your script's location in our GitHub # repository) to access the dictionary of common words from Week #161. # # Optional Extras (for an 0xAddedFee, of course!) # -# Limit the number of “special” letter substitutions in any one result to +# Limit the number of "special" letter substitutions in any one result to # keep that result at least somewhat comprehensible. (0x51105010 is an # actual example from my sample solution you may wish to avoid!) # diff --git a/challenge-166/paulo-custodio/perl/ch-2.pl b/challenge-166/paulo-custodio/perl/ch-2.pl index f65656bcab..cb92177a74 100644 --- a/challenge-166/paulo-custodio/perl/ch-2.pl +++ b/challenge-166/paulo-custodio/perl/ch-2.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Challenge 166 # diff --git a/challenge-166/paulo-custodio/python/ch-1.py b/challenge-166/paulo-custodio/python/ch-1.py new file mode 100644 index 0000000000..b64b0f1337 --- /dev/null +++ b/challenge-166/paulo-custodio/python/ch-1.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# Challenge 166 +# +# Task 1: Hexadecimal Words +# Submitted by: Ryan J Thompson +# +# As an old systems programmer, whenever I needed to come up with a 32-bit +# number, I would reach for the tired old examples like 0xDeadBeef and +# 0xC0dedBad. I want more! +# +# Write a program that will read from a dictionary and find 2- to 8-letter +# words that can be "spelled" in hexadecimal, with the addition of the following +# letter substitutions: +# +# o -> 0 (e.g., 0xf00d = "food") +# l -> 1 +# i -> 1 +# s -> 5 +# t -> 7 +# +# You can use your own dictionary or you can simply open +# ../../../data/dictionary.txt (relative to your script's location in our GitHub +# repository) to access the dictionary of common words from Week #161. +# +# Optional Extras (for an 0xAddedFee, of course!) +# +# Limit the number of "special" letter substitutions in any one result to +# keep that result at least somewhat comprehensible. (0x51105010 is an +# actual example from my sample solution you may wish to avoid!) +# +# Find phrases of words that total 8 characters in length +# (e.g., 0xFee1Face), rather than just individual words. + +import sys + +if len(sys.argv) != 2: + sys.exit("usage: ch-1.py words.txt") + +f = open(sys.argv[1], "r") +for line in f.readlines(): + word = line.strip() + if len(word) >= 2 and len(word) <= 8 and all(c in 'abcdef0list' for c in word.lower()): + word = word.translate(str.maketrans('olist', '01157')) + print("0x" + word.upper()) diff --git a/challenge-166/paulo-custodio/python/ch-2.py b/challenge-166/paulo-custodio/python/ch-2.py new file mode 100644 index 0000000000..a47b99586a --- /dev/null +++ b/challenge-166/paulo-custodio/python/ch-2.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +# Challenge 166 +# +# Task 2: K-Directory Diff +# Submitted by: Ryan J Thompson +# +# Given a few (three or more) directories (non-recursively), display a +# side-by-side difference of files that are missing from at least one of the +# directories. Do not display files that exist in every directory. +# +# Since the task is non-recursive, if you encounter a subdirectory, append a /, +# but otherwise treat it the same as a regular file. +# Example +# +# Given the following directory structure: +# +# dir_a: +# Arial.ttf Comic_Sans.ttf Georgia.ttf Helvetica.ttf Impact.otf Verdana.ttf +# Old_Fonts/ +# +# dir_b: +# Arial.ttf Comic_Sans.ttf Courier_New.ttf Helvetica.ttf Impact.otf +# Tahoma.ttf Verdana.ttf +# +# dir_c: +# Arial.ttf Courier_New.ttf Helvetica.ttf Impact.otf Monaco.ttf Verdana.ttf +# +# The output should look similar to the following: +# +# dir_a | dir_b | dir_c +# -------------- | --------------- | --------------- +# Comic_Sans.ttf | Comic_Sans.ttf | +# | Courier_New.ttf | Courier_New.ttf +# Georgia.ttf | | +# | | Monaco.ttf +# Old_Fonts/ | | +# | Tahoma.ttf | + +import os +import sys + +WIDTH = 16 + +def read_dir(dir): + try: + with os.scandir(dir) as entries: + return sorted((entry.name + '/' if entry.is_dir() else entry.name) for entry in entries if entry.name not in {'.', '..'}) + except OSError as e: + print(f"opendir {dir}: {e}", file=sys.stderr) + sys.exit(1) + +def read_dirs(*dirs): + return [read_dir(dir) for dir in dirs] + +def print_line(*cells): + for i in range(len(cells)): + print(f"{cells[i]:<{WIDTH}}", end=" | " if i != len(cells) - 1 else "") + print() + +def print_diff(dirs, contents): + # print header + print_line(*dirs) + print_line(*(["-" * WIDTH] * len(dirs))) + + # collect files + files = {} + files_dir = {} + for i, dir in enumerate(dirs): + for file in contents[i]: + files[file] = True + if file not in files_dir: + files_dir[file] = {} + files_dir[file][dir] = True + + # print rows + for file in sorted(files.keys()): + row = [file if dir in files_dir.get(file, {}) else "" for dir in dirs] + if any(cell == "" for cell in row): + print_line(*row) + +if len(sys.argv) > 2: + print_diff(sys.argv[1:], read_dirs(*sys.argv[1:])) diff --git a/challenge-166/paulo-custodio/t/dir_a/Old_Fonts/.keep b/challenge-166/paulo-custodio/t/dir_a/Old_Fonts/.keep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/challenge-166/paulo-custodio/t/dir_a/Old_Fonts/.keep |
