Sunday, June 27, 2021

US City, Japanese Food (Preview)

It's Sunday, and we all know what that means.

Let's take a crack at this week's Sunday Puzzle from NPR Puzzlemaster Will Shortz:

This week's challenge comes from listener Julia Lewis, of Fort Collins, Colo. Take the name of a major American city. Hidden inside it in consecutive letters is the name of a Japanese food. Remove that. The remaining letters can be rearranged to to spell some Mexican foods. Name the city and the foods.

 

As usual, let's start with a list of our needs:

  • C: A list of major American cities;
  • J: A list of Japanese foods;
    • This has to fit inside the city name, so it's probably short; I'm guessing it's one of these: sushi, ramen, tofu... we'll expand that if we don't get any matches;
  • M: A list of Mexican foods;
    • This target word also has to fit in the scrambled remaining letters of the city, so it also needs to be short; I'm going to start with: taco, nacho, salsa... We can expand later if needed;
So first, we'll do some text normalization on C, the list of American cities; lowercase, strip spaces and non-letters, like this:
  • St. Paul --> stpaul
  • Wilkes-Barre --> wilkesbarre
We'll also want to make sure our foods in J and M are lowercased (I don't expect spaces or non-letters anyway, as these words need to be short enough to be a substring of the city name; we might get accented characters in the Mexican list, so we'll want to strip those down to simple ASCII).

Then we'll want to do something like this:
  • for city in C:
    • for jfood in J:
      • if jfood in city:
        • print(city, jfood)
From there, it would probably be easy to "eyeball" this problem and determine what Mexican food we can spell from the remaining letters in the city name. But let's play this out fully anyway. So, we continue by removing the Japanese food substring from the city name, then iterating through our list of Mexican foods to see which we can spell with the remaining letters. We might want to be a bit flexible for the sake of handling plurals. If I'm not mistaken, Spanish plurals are always formed by adding "-s" or "-es", so we can simply check for such variations.
        • cityletters = city.replace(jfood, "")
        • cityletters = list(cityletters)
        • cityletters.sort()
        • cityletters = "".join(cityletters)  ##now we have a sorted string for easy comparison
        • for mf1 in mfoods:  ##get sorted strings for mexican food and plural variants
          • mf2 = mf1+"s"
          • mf3 = mf1+"es"
          • mf1letters = list(mf1)
          • mf2letters = list(mf2)
          • mf3letters = list(mf3)
          • mf1letters.sort()
          • mf2letters.sort()
          • mf3letters.sort()
          • m1 = "".join(mfletters)
          • m2 = "".join(mf2letters)
          • m3 = "".join(mf3letters)
          • if cityletters in [m1, m2, m3]:
            • print(city, jfood, mf)
That should do it. Good luck! I'll post my solution later this week. :-)

--Levi King

Saturday, June 26, 2021

Car Makes and Girl Names (Solution)

Welcome back, Puzzlers. I'm back to share my solution to the latest Sunday Puzzle from NPR. Scroll to the bottom to see it. Here's the puzzle again:

This week's challenge comes from listener Iva Allen in Canada. Name a make of car. Write it in all capital letters. Rotate one of the letters 90 degrees and another letter 180 degrees to make a woman's name. What is it?

In the preview post, I shared this breakdown:


    What do we need in order to solve this?

    • C: A list of car "makes"; let's assume this means "brands" or "manufacturers";
    • G: A list of girl names;
    • R90: A dictionary mapping of capital letters that can be rotated 90 degrees to form a new letter;
      • {'C': 'U', ...}
    • R180: A dictionary mapping of capital letters that can be rotated 180 degrees to form a new letter;
      • {'M': 'W', ...}
    Now, we iterate through each car maker. Then we'll need to iterate through the letters and determine which ones are in R90 and R180---we make a list of all indices in the string where the letter at that index can be rotated 90 degrees, and another list of indices for 180 degrees. Then we use something like "itertools.product()" to generate all pairs of one 90-degree position and one 180-degree position (where the two positions are not the same---we want to rotate two different letters (indices) in the string). Then we take this "agenda" of pair rotations and apply the rotation mappings to the original string, so we have all possible strings generated from the car maker string. For example:

    ACURA --> ['VUURA', 'AUARA', 'VCCRA']

    Then, we simply iterate through each of these variants and compare it against G, the list of girls' names and print out the car maker and the girl name when find a match.


      And that's how I solved it! If you'd like to see my approach in detail, I've shared my solver script here, and you'll also need my list of car makes and my list of girls' names.

      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .
      .

      MAZDA --> WANDA

      Did you get this solution too?

      See you next week!
      --Levi King

        Monday, June 21, 2021

        Car Makes and Girl Names (Preview)

        Welcome back, Puzzlers. Let's take a crack at the latest Sunday Puzzle from NPR:

        This week's challenge comes from listener Iva Allen in Canada. Name a make of car. Write it in all capital letters. Rotate one of the letters 90 degrees and another letter 180 degrees to make a woman's name. What is it?

        What do we need in order to solve this?

        • C: A list of car "makes"; let's assume this means "brands" or "manufacturers";
        • G: A list of girl names;
        • R90: A dictionary mapping of capital letters that can be rotated 90 degrees to form a new letter;
          • {'C': 'U', ...}
        • R180: A dictionary mapping of capital letters that can be rotated 180 degrees to form a new letter;
          • {'M': 'W', ...}
        Now, we iterate through each car maker. Then we'll need to iterate through the letters and determine which ones are in R90 and R180---we make a list of all indices in the string where the letter at that index can be rotated 90 degrees, and another list of indices for 180 degrees. Then we use something like "itertools.product()" to generate all pairs of one 90-degree position and one 180-degree position (where the two positions are not the same---we want to rotate two different letters (indices) in the string). Then we take this "agenda" of pair rotations and apply the rotation mappings to the original string, so we have all possible strings generated from the car maker string. For example:

        ACURA --> ['VUURA', 'AUARA', 'VCCRA']

        Then, we simply iterate through each of these variants and compare it against G, the list of girls' names and print out the car maker and the girl name when find a match.

        Sounds simple enough, right? I'll be back after the Thursday NPR submission deadline to share my solution. Good luck!

        Thursday, June 17, 2021

        Famous Woman from American History, Famous Athlete (Solution)

        Welcome back, Puzzlers. Spoiler warning: The puzzle solution is posted at the end of this page.

        Ready to solve the latest Sunday Puzzle from NPR?

        This week's challenge comes from listener Sandy Weisz, of Chicago. Name a famous woman in American history with a three-part name. Change one letter in her first name to a double letter. The resulting first and second parts of her name form the first and last names of a famous athlete. And the last part of the woman's name is a major rival of that athlete. Who are these people?

        If you're still working this puzzle, you may want to check my preview post where I discussed the puzzle in more depth.

        We determined that we need these things:

        • W: a list of women from American history; each must have a name that can be represented in three parts;
          • I came up with a pretty short list, so I just included it directly in my solver script;
        • A: a list of famous athletes;
        • fx_double_letter: a function to iterate through the letters in each first name and double OR replace AND double, returning a list of the resulting "names";
        So from there, it's pretty straightforward. We iterate through each woman in W, apply fx_double_letter, check each resulting first and second name against list A; when we find a match, we also need to check the third name for a match in list A. Because I'm only using one list of athletes, I'll need to confirm the "rival" part of the puzzle to be true.

        And that's how I solved it. If you want to try my solver script, you can download it from the companion GitHub repo for this blog, as always.

        As I discussed in the preview, the wording of this puzzle was a little bit tricky.
        The double letter is a different letter; you have to replace the letter and then double it.

        Here's my solution, below:
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        .
        Lady Bird Johnson --> Larry Bird, (Earvin 'Magic') Johnson

        Did you get the same solution?

        See you next week!
        --Levi King

        Monday, June 14, 2021

        Famous Woman from American History, Famous Athlete (Preview)

        Welcome back, Puzzlers. Let's continue our winning streak with the latest Sunday Puzzle from NPR:

        This week's challenge comes from listener Sandy Weisz, of Chicago. Name a famous woman in American history with a three-part name. Change one letter in her first name to a double letter. The resulting first and second parts of her name form the first and last names of a famous athlete. And the last part of the woman's name is a major rival of that athlete. Who are these people?

        I'll preface this by saying that I've already solved it just by doing a little brainstorming, but I'm going to apply my usual systematic approach and try to get the solution that way, too. It's good practice. I'm not going to spoil it here, so you can try to brainstorm for it or implement your own approach.

        Okay, let's break this down. There's some real cagey language in this puzzle. Why does it refer to a "three-part name"? Is that different from "three names"? Is it not just a first, middle and last name? Is there some kind of hyphenation or honorific or nickname involved? We don't really know what that means, so we'll have to be flexible in what possibilities we allow for.

        "Change one letter in her first name to a double letter." I guess we have to assume "first name" here means "first of three parts of her name." The change part of this isn't quite clear, either. Do we just double an existing letter, e.g., Ana --> Anna and Lily --> Lilly? It's worth noting that after glancing through a list of girl's names, there aren't a lot of first names amenable to this transformation. The other way to interpret this clue is that the letter is replaced with a different doubled letter, e.g., Ava --> Anna or Jody --> Jonny. Again, since we don't know, I think it's best if we allow for either interpretation.

        "The resulting first and second parts of her name form the first and last names of a famous athlete." Again, we'll assume this is the first and second parts of the three part name. Is this a man or woman? We don't know.

        "And the last part of the woman's name is a major rival of that athlete." This is the least concerning part--the last name remains a last name.

        What do we need here?

        • W: a list of women from American history; each must have a name that can be represented in three parts;
        • A: a list of famous athletes;
        • fx_double_letter: a function to iterate through the letters in each first name and double OR replace AND double, returning a list of the resulting "names";
        So from there, it's pretty straightforward. We iterate through each woman in W, apply fx_double_letter, check each resulting first and second name against list A; when we find a match, we also need to check the third name for a match in list A. Because I'm only using one list of athletes, I'll need to confirm the "rival" part of the puzzle to be true.

        That's my plan. I'll be back later this week with my solution. Good luck!

        Friday, June 11, 2021

        Country, Capital, Best Picture (Solution)

        Welcome back! I'm happy to report that I "definitely, definitely" solved the latest Sunday Puzzle from NPR. Here's the puzzle, and you can scroll to the bottom of this post for the solution:


        This week's challenge comes from listener Matthew Leal of San Francisco. Write down the name of a country plus its capital, one after the other. Hidden in consecutive letters inside this is the name of a film that won an Academy Award for Best Picture. Name the country, capital, and film.

        In the preview, I mentioned that we would need:
        You'll need to the files linked above in order to run my solver script, or you may want to use them in your own script. My solver script is available here on the companion GitHub repository for this blog.
        As discussed in this week's preview post, my approach works like this:

        As usual, we'll need to clean and format our data a little to make it suitable for the kind of comparison we're doing. For each country, capital, and movie, we'll want to lowercase all letters, remove any non-letters (spaces, apostrophes, hyphens). I also like to use a python package called Slugify for this kind of task; slugify converts unicode letters into their nearest ASCII equivalent. This means that "Curaçao" becomes "Curacao", etc. We'll also want to concatenate the country+capital, with no spaces, and we'll want to do the same for all the words in the movie title.

        For example:
          • Domincican Republic, Santo Domingo --> dominicanrepublicsantodomingo
          • Côte d'Ivoire, Yamoussoukro --> cotedivoireyamoussoukro
          • Ben-Hur --> benhur
          • The Shape of Water --> theshapeofwater
        Then we simply need to iterate through these lists and see if we find a movie title inside a country+capital string.
          • for cstring in countries_capitals:
            • for mstring in movies:
              • if mstring in cstring:
                • print(cstring)
                • print(mstring)

        Solution:
        Bahrain, Manama --> Rain Man

        See you for the next puzzle!

        --Levi King

        Monday, June 07, 2021

        Country, Capital, Best Picture (Preview)

        Hello Puzzlers. Let's take a crack at the latest Sunday Puzzle from NPR:

        This week's challenge comes from listener Matthew Leal of San Francisco. Write down the name of a country plus its capital, one after the other. Hidden in consecutive letters inside this is the name of a film that won an Academy Award for Best Picture. Name the country, capital, and film.


        Okay, let's inventory our needs for this puzzle:
        • CC: a list of countries and capitals;
        • BP: a list of Best Picture winners;
        As usual, we'll need to clean and format our data a little to make it suitable for the kind of comparison we're doing. For each country, capital, and movie, we'll want to lowercase all letters, remove any non-letters (spaces, apostrophes, hyphens). I also like to use a python package called Slugify for this kind of task; slugify converts unicode letters into their nearest ASCII equivalent. This means that "Curaçao" becomes "Curacao", etc. We'll also want to concatenate the country+capital, with no spaces, and we'll want to do the same for all the words in the movie title.

        For example:
        • Domincican Republic, Santo Domingo --> dominicanrepublicsantodomingo
        • Côte d'Ivoire, Yamoussoukro --> cotedivoireyamoussoukro
        • Ben-Hur --> benhur
        • The Shape of Water --> theshapeofwater
        Then we simply need to iterate through these lists and see if we find a movie title inside a country+capital string.
        • for cstring in countries_capitals:
          • for mstring in movies:
            • if mstring in cstring:
              • print(cstring)
              • print(mstring)
        And that's how we solve this puzzle!

        Actually, this is a relatively easy one to solve without any scripting. If you just skim through a list of countries and their capitals, you're likely to spot the name of the movie. But it's fun to script a solution just for fun, so I'm trying it with Python as well.

        Good luck! I'll post my script and solution on Friday, after the NPR submission deadline has passed.

        --Levi King

        Thursday, June 03, 2021

        Cities and letter values (Solution)

         Now that the deadline to submit solutions has passed, let's solve this week's puzzle:

        This week's challenge comes from listener Al Gori, of Oak Ridge, N.J. Name a famous city in 10 letters that contains an "S." Drop the "S." Then assign the remaining nine letters their standard value in the alphabet — A = 1, B= 2, C = 3, etc. The total value of the nine letters is only 25. What city is it?

        In my preview post, I suggested we start with these:

        • C: a list of cities;
          • I'm planning to use this one; it looks pretty good, and it's downloadable as a CSV, so we can easily pull the names from that without needing to scrape and clean HTML.
          • We'll filter this so that we keep only city names that contain 10 letters (not counting spaces, hyphens, etc.) and exactly one 's'.
        • function_lvsLetter value sum function to take a string (a city name), look up the numerical value in the alphabet for each letter (minus the 's') and return that sum;
          • for c in C
            • if function_lvs(c) == 25:
              • print("Solution! "+c)
        And that's pretty much how I solved it. 

        I filtered my list of cities down to these, which all contain exactly 10 letters including exactly 1 's'; note that they are lowercased with spaces and non-letters removed:

        addisababa
        casablanca
        faisalabad
        manchester
        lubumbashi
        jamshedpur
        sanantonio
        liupanshui
        saharanpur
        kermanshah
        valparaiso
        hermosillo
        washington
        khabarovsk
        louisville
        almansurah
        santamarta
        rustenburg
        balashikha
        arrusayfah
        sacramento
        utsunomiya
        cheboksary
        suratthani

        From there, we just need to sum all the letter values except for the 's', and check if it's equal to 25. Obviously, if letter values can range from 1 to 26 and the sum of our 9 letters is only 25, our letters need to come primarily from the beginning of the alphabet.

        Have you got it? You can see my solver script here on GitHub, and I've added the solution at the bottom of the script, so check it there if you just want the solution.

        Tuesday, June 01, 2021

        Cities and letter values (Preview)

        Apologies for my absence, Puzzlers! I'm currently wrapping up a huge personal project, but I'll try to keep up with this puzzle blog going forward.

        This week's puzzle is a pretty straightforward solve, fortunately. Let's take a look:

        This week's challenge comes from listener Al Gori, of Oak Ridge, N.J. Name a famous city in 10 letters that contains an "S." Drop the "S." Then assign the remaining nine letters their standard value in the alphabet — A = 1, B= 2, C = 3, etc. The total value of the nine letters is only 25. What city is it?

         To solve this puzzle, we need:

        • C: a list of cities;
          • I'm planning to use this one; it looks pretty good, and it's downloadable as a CSV, so we can easily pull the names from that without needing to scrape and clean HTML.
          • We'll filter this so that we keep only city names that contain 10 letters (not counting spaces, hyphens, etc.) and exactly one 's'.
        • function_lvs: Letter value sum function to take a string (a city name), look up the numerical value in the alphabet for each letter (minus the 's') and return that sum;
          • for c in C
            • if function_lvs(c) == 25:
              • print("Solution! "+c)
        Come back here after NPR's Thursday deadline to see my solution and implementation. Good luck!

        Director, anagram, film award

        Welcome back to Natural Language Puzzling, the blog where we use natural language processing and linguistics to solve the Sunday Puzzle from...