okay, this is not exactly a #toyprogrammingchallenge but I hope you hate this problem as much as I did...
The problem is not just getting the right solution, but getting it in under the running timeout of 12000 ms. Good luck.
Here's a #toyprogrammingchallenge requiring a bit of algebra.
For any four non-collinear points A, B, C, and D in three-dimensional space, there is a unique hyperbolic paraboloid H containing the lines AB, BC, CD, and AD (that is, every point on any of these lines is also on the surface of H). Write a program that accepts Cartesian coordinate triplets representing A, B, C, and D and prints an equation in x, y, and z that is satisfied if and only if <x, y, z> is a point on H.
Your program's output may differ from the examples but should be optimised for human readability. Combine like terms, omit terms equal to zero and avoid unnecessary factors (e.g. prefer "x = y" to "2x + 0 = 4y - 2y" even though both describe the same surface).
Example 1 input:
<0, 1, -1>; <1, 0, 1>; <0, -1, -1>; <-1, 0, 1>
Example 1 output:
z = x² - y²
Example 2 input:
<1, 1, 1>; <1, 0, -1>; <-1, 1, -1>; <-1, 0, 1>
Example 2 output:
2y = xz + 1
Example 3 input:
<0, 1, 1>; <0, 1, -1>; <0, -1, -1>; <0, -1, 1>
Example 3 output:
x = 0
Octave solution & discussion
Pretty straightforward. Might be possible to improve on the factorial one by counting factors, because computers can generally calculate x^n faster than just multiplying it out, so if you figure out that the answer would be 2^a * 3^b * 5^c... it could outpace the naive 1 * 2 * 3 * ... * n method.
That said, I tried such an approach and while it does scale better than linear, the upfront cost is high enough that the breakeven point is way past anything my computer can represent in floating point. So for practical use, this is what I'd put forward.
function term = fibonacci(index)
root = sqrt(5);
term = (((1 + root)/2).^index - ((1 - root)/2).^index) ./ root; end;
function number = factorial(argument)
number = ones(size(argument));
for factor = 1:max(argument)
number(argument >= factor) *= factor; end; end;
Kind of feels like I am phoning this one in, but I really liked this puzzle and hadn't really seen it before. However, if you have already seen this (and it is likely that you have) feel free to just ignore it.
Given a short message containing no more than 10 unique letters
written in the form of a simple equasion. Show the numeric values
for the letters to make it true. No letter that starts a word can
have the value Zero.
For example:
I + LOVE + YOU == DORA
1 + 2784 + 975 == 3760
Here is an interesting that is true in both cases, and will have only one solution:
ONE + TWO + FIVE + NINE + ELEVEN + TWELVE + FIFTY = NINETY
Still trying to find a style i like for the double L... Thoughts on this one?
Octave solution
Should be fairly easy to modify for other bracket types, just add them to the lists at the top and bottom (using the same index for an open bracket and its corresponding close bracket).
function valid = is_balanced(string)
open_brackets = '({[';
close_brackets = ')}]';
expecting = false(size(string));
valid = true;
expected_bracket = [];
for index = 1:numel(string)
if ismember(string(index), open_brackets)
expecting(index) = true;
expected_bracket = strchr(open_brackets, string(index));
elseif ismember(string(index), close_brackets)
if expected_bracket == strchr(close_brackets, string(index))
expecting(find(expecting, 1, 'last')) = false;
expected_bracket = strchr(open_brackets, string(find(expecting, 1, 'last')));
else
valid = false; end; end; end;
if any(expecting)
valid = false; end; end;
Octave solution
Matlab normally represents strings as 1D arrays of chars. It's not usual to put chars in an 2D array because all the rows would have to be the same length, and that's pretty inflexible. Octave is happy to make such an array just as it would with any other type, though, and here that's exactly what we want.
function array = justify_text(string, width)
words = strtrunc(strsplit(string), width);
array = zeros(0, width);
line_length = 0;
start_index = 1;
for word_index = 1:numel(words)
this_word = words{word_index};
if line_length + numel(this_word) > width
array = [array; render_words(start_index, word_index - 1)];
start_index = word_index;
line_length = numel(this_word) + 1;
else
line_length += numel(this_word) + 1; end; end;
array = [array; render_words(start_index, numel(words))];
function this_line = render_words(start_index, end_index)
chars_raw = cellfun(@numel, words(start_index:end_index));
total_padding = width - sum(chars_raw);
if start_index == end_index
this_line = [words{start_index} repmat(' ', 1, total_padding)];
else
base_padding = floor(total_padding / (end_index - start_index));
extra_padding = rem(total_padding, end_index - start_index);
next_char = 1;
for index = start_index:end_index
this_padding = 0;
if index < end_index
this_padding = base_padding;
if index - start_index < extra_padding
this_padding++; end; end;
this_line(next_char:(next_char + chars_raw(index - start_index + 1) - 1)) = words{index};
next_char += chars_raw(index - start_index + 1);
this_line(next_char:(next_char + this_padding - 1)) = repmat(' ', 1, this_padding);
next_char += this_padding; end; end; end; end;
Octave solution
This was super straightforward. Linear in time and space, plus whatever the sort algorithm needs (by default it's nlogn in Octave but you can implement other ones).
function room_count = min_rooms(class_times)
[~, indices] = sort(class_times'(1:numel(class_times)));
current = 0;
room_count = 0;
for index = indices
if mod(index, 2)
current++;
room_count = max(room_count, current);
else
current--; end; end; end;
Basic non regex solution
@Absinthe@qoto.org I just did, pretty interesting.
Python-ish solution
I am not happy with the pythonicallity of this, but it solves the problem...
Okay, here's one. I just finished helping someone worth through this. So it's pretty fun.
Write a program in Python, that can accept a paragraph string and and page
width and return an array of left AND right justified strings. NOTE: No words
should be broken, the beginning and end of the line should be characters).
You should provide instructions on how to execute your program and provide a
sample output.
Example:
Sample input:
Paragraph = "This is a sample text but a complicated problem to be solved, so
we are adding more text to see that it actually works."
Page Width = 20
Output should look like this:
Array [1] = "This is a sample"
Array [2] = "text but a"
Array [3] = "complicated problem"
Array [4] = "to be solved, so we"
Array [5] = "are adding more text"
Array [6] = "to see that it"
Array [7] = "actually works.”
Okay, here's one. I just finished helping someone worth through this. So it's pretty fun.
Write a program in Python, that can accept a paragraph string and and page
width and return an array of left AND right justified strings. NOTE: No words
should be broken, the beginning and end of the line should be characters).
You should provide instructions on how to execute your program and provide a
sample output.
Example:
Sample input:
Paragraph = "This is a sample text but a complicated problem to be solved, so
we are adding more text to see that it actually works."
Page Width = 20
Output should look like this:
Array [1] = "This is a sample"
Array [2] = "text but a"
Array [3] = "complicated problem"
Array [4] = "to be solved, so we"
Array [5] = "are adding more text"
Array [6] = "to see that it"
Array [7] = "actually works.”
Another Python Using Generators
"""Example using generators for run length encode/decode."""
def rleunits(str1):
"""Generate run length encoded units."""
current = None
count = 0
for letter in str1:
if letter == current:
count += 1
else:
if current:
yield str(count)+current
count = 1
current = letter
def rldunits(str1):
"""Generate run length decoded units."""
count = None
for c in str1:
if c.isdigit():
if not count:
count = c
else:
count += c
else:
yield(c * int(count))
count = None
def main():
"""Drive the example."""
str1 = "AAAABBBBCDDEEFFFFFFFFFFF"
encoded = ''.join(rleunits(str1))
print(encoded)
unencoded = ''.join(rldunits(encoded))
print(unencoded)
main()
Basic non regex solution
@Absinthe@qoto.org
def encode(input):
out = ""
let = input[0]
num = 1
for i in range(1, len(input)):
if input[i] == input[i-1]:
num = num + 1
else:
out = out + str(num) + input[i-1]
let = input[i]
num = 1
out = out + str(num) + input[len(input)-1]
return out
def decode(input):
out = ""
i = 0
while i != (len(input)):
for p in range(0, int(input[i])):
out = out + input[i+1]
i = i + 2
return out
Here is a #toyprogrammingchallenge which corresponds to the general case of a problem I ran up against recently.
Given a positive integer K and a directed graph G with weighted edges, return a new graph H satisfying all the following conditions, if such a graph exists:
1. G and H contain exactly the same set of vertices.
2. H contains only edges in G, but G may contain edges not in H.
3. A path exists in H of length at most K between each pair of vertices in each direction.
4. No edge can be removed from H while still satisfying condition 3.
Where more than one graph exists satsifying these conditions, return the one with the least total weight. You may assume G does not contain edges with negative weights.
Here is an example G, each triplet representing the <start, end, weight> of an edge:
<1, 2, 40>
<1, 3, 12>
<1, 4, 50>
<2, 1, 84>
<2, 3, 19>
<2, 4, 69>
<3, 1, 25>
<3, 2, 78>
<3, 4, 93>
<4, 1, 75>
<4, 2, 36>
<4, 3, 96>
Your program should produce the following H given the above G and K = 2:
<1, 2, 40>
<1, 4, 50>
<2, 1, 84>
<2, 3, 19>
<3, 1, 25>
<4, 2, 36>
SPOILER ONE-LINER SOLUTIONS IN PYTHON
import re
encooded = "14A3B2C1D2A"
decoded = ""
# first attempt at decoding
list1 = re.findall('\d+\D', encooded)
for l in list1:
count, char = int(l[0:-1]) , l[-1]
decoded += ''.join(count * char)
print(decoded)
# one-liner using regex for decoding!
print(''.join([ int(l[0:-1]) * l[-1] for l in re.findall('\d+\D', encooded) ]))
# one liner using regex for encoding
print( ''.join([ str(len(match[1])+1) + match[0] for match in re.findall(r"(.)(\1*)", decoded)]))
Wow, lots of followers today!
If you are interested in any of my coding challenges they should all be tagged with : #toyprogrammingchallenge
If you put that in your search and scroll to to bottom you will see my original proposal. Here is a link with the explanation of where my head is at. The ones I post that I call freebies, are from a subscription to Job Interview problems, and they should be a little tricky, but are usually rated as easy, medium or hard.
The green faerie