|
Programming Guru
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 1,888
Rep Power: 5 
|
SMAC #2 [06-08] - Swapping Stories (Beginner)
Attached to this post is the test data for swapping stories.
Swapping Stories (Beginner)
Swapping stories was mainly an exercise in reading comprehension and how well you know the language.
If you can manage basic string manipulation and searching, this problem should be a walk in the park.
The algorithm to complete the task is also fairly intuitive.
1) Read a query
2) If the query says "no", go back to step 1
3) If the query says "yes", find each floor in the stack of papers
4) Swap the position of the two floors
5) Repeat
The way you do step 3 is up to you. You can search the entire list, you can use a dictionary, etc...
My solution simply does a search with Python's ".index()" method. It's not as fast as a dictionary, but it's easy to code.
Here is Titanium Decoy's solution which implements his own "index" method. His solution scored perfect.
/* * SMAC #2 * titaniumdecoy */ #include <stdio.h> #include <stdlib.h> #include <string.h> char *next_token(void) { static char buf[21]; char *string = NULL; scanf("%s", buf); string = (char *)malloc(sizeof(char) * (strlen(buf) + 1)); strcpy(string, buf); return string; } int index_of(char **array, int array_len, char *str) { int i = 0; for (i = 0; i < array_len; i++) if (strcmp(array[i], str) == 0) return i; return -1; } void swap(char **array, int a, int b) { char *tmp = NULL; tmp = array[a]; array[a] = array[b]; array[b] = tmp; } int main() { int i = 0; int n = 0, q = 0; char **floors = NULL; char s1[21]; char s2[21]; char yn[4]; int x = 0, y = 0; freopen("swap.in", "r", stdin); freopen("swap.out", "w", stdout); scanf("%d %d", &n, &q); floors = (char **)malloc(sizeof(char *) * n); for (i = 0; i < n; i++) floors[i] = next_token(); for (i = 0; i < q; i++) { scanf("%s %s %s", s1, s2, yn); if (strcmp(yn, "yes") == 0) { x = index_of(floors, n, s1); y = index_of(floors, n, s2); swap(floors, x, y); } } for (i = 0; i < n; i++) printf("%s\n", floors[i]); return 0; }
Jimbo's solution overkills the problem with a dictionary. It also scored perfect.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace SMAC2_Beginner { class Program { class SwapRule { public string First; public string Second; public bool Swap; public SwapRule(string s) { string[] parts = s.Split(" ".ToCharArray()); First = parts[0]; Second = parts[1]; Swap = parts[2].Equals("yes", StringComparison.InvariantCultureIgnoreCase); } } // strategy: // Read all the stories into a List // Keep them also in a dictionary so I know the original order // Apply any swap rules that contain "yes" // Swap the items in the list to their final places after all the swapping logic is done static void Main(string[] args) { StreamReader swapIn = null; StreamWriter swapOut = null; try { swapIn = new StreamReader("swap.in"); string buffer = swapIn.ReadLine(); int n, q; string[] nums = buffer.Split(" ".ToCharArray()); n = int.Parse(nums[0]); q = int.Parse(nums[1]); Dictionary<string, int> storyIndices = new Dictionary<string, int>(); List<string> stories = new List<string>(); List<SwapRule> swapRules = new List<SwapRule>(); // read in stories for (int i = 0; i < n; i++) { string storyName = swapIn.ReadLine(); storyIndices.Add(storyName, i); stories.Add(storyName); } // read in swap rules for (int i = 0; i < q; i++) { String swapLine = swapIn.ReadLine(); SwapRule temp = new SwapRule(swapLine); // swap if the rule says yes if (temp.Swap) { int a = storyIndices[temp.First]; storyIndices[temp.First] = storyIndices[temp.Second]; storyIndices[temp.Second] = a; } } // now sort them after the swapping's done for (int i = 0; i < stories.Count; i++) { // need to loop doing this until storyIndices[stories[i]] == i, or else we don't have the right one in place // even with the nested loop, number of swaps will be O(n), since with each swap, one element is put into the // correct index while (storyIndices[stories[i]] != i) { swapListItems<string>(stories, i, storyIndices[stories[i]]); } } // dump results swapOut = new StreamWriter("swap.out"); foreach (string s in stories) { #if DEBUG Console.WriteLine(s); #endif swapOut.WriteLine(s); } swapOut.Flush(); } catch(Exception e) { Console.WriteLine(String.Format("Error encountered, aborting. Error: [{0}]", e.ToString())); } finally { if (swapIn != null) { swapIn.Close(); swapIn = null; } if (swapOut != null) { swapOut.Close(); swapOut = null; } } } private static void swapListItems<T>(List<T> l, int a, int b) { T temp = l[a]; l[a] = l[b]; l[b] = temp; } } }
And the official solution in Python:
def scanf(line, *args): toks = line.replace('\n', '').split(' ') for i in range(len(args)): yield args[i](toks[i]) fin = open("swap.in", "r").readlines() n, q = scanf(fin[0], int, int) # Parse each floor name floors = [] for i in range(n): floors.append(scanf(fin[i+1], str).next()) # Parse each query for i in range(q): f1, f2, cmd = scanf(fin[i+n+1], str, str, str) if cmd == "yes": # Search for each floor name i1 = floors.index(f1) i2 = floors.index(f2) # Swap the two floors names temp = floors[i1] floors[i1] = floors[i2] floors[i2] = temp # Output the results fout = open("swap.out", "w") for i in range(n): fout.write("%s\n"%floors[i]) fout.close()
|