Problem of the Day
A new programming or logic puzzle every Mon-Fri

Where To Eat?

In my first couple of years in college I used to eat out a lot. One of the first programs I made in college was for my buddies and I to pick a place to eat. It's was a rather simple program. Took in a list of places to eat from a text file and chose one randomly.

I think it's about time for a slight upgrade though. Today's problem will be to implement the random food picker program and to also make sure that the same place isn't selected twice in a row. This means that your program will need to remember what it chose the last time it ran. Either via text file, HTML5 localstorage, database, etc.

Permalink: http://problemotd.com/problem/where-to-eat/

Comments:

  • Carlos - 10 years, 8 months ago

    Java code is always huge, so there's that. Pretty straightforward problem, just use the last line in the folder, or the first, to save the last place you were.

    private static final List<String> places = new ArrayList();
    private static final Random rng = new Random();
    private static String content = "";
    private static int rndN = 0;
    
    public static void main(String[] args) {
        testCase();
    }
    
    public static void testCase() {
        pickPlace();
    }
    
    public static void pickPlace() {
        getPlaces();
        chooseNewPlace();
        placeNewContent();
        organizeFolder();
    }
    
    private static void getPlaces() {        
        BufferedReader br = null; 
    try {
            String sCurrentLine;
            br = new BufferedReader(new FileReader(System.getProperty("user.dir") + "\\others\\Day25_WhereToEat.txt"));
            while ((sCurrentLine = br.readLine()) != null) {
                places.add(sCurrentLine);
            }
        } catch (IOException e) {
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException ex) {}
        }
    }
    
    private static void chooseNewPlace() {
        rndN = rng.nextInt(places.size());
        while(places.get(rndN).equals(places.get(places.size() - 1))) {
            rndN = rng.nextInt(places.size() - 1);
        }
    
        System.out.println("Place chosen was: " + places.get(rndN));        
        for(int i=0; i<places.size() - 1; i++) {
            content += places.get(i) + "\n";
        }  
    
        content += places.get(rndN);
    }
    
    private static void placeNewContent() {        
        try {
            File file = new File(System.getProperty("user.dir") + "\\others\\tmp.txt");
            if (!file.exists()) {
                file.createNewFile();
            }
    
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(content);
            bw.close();
        } catch (IOException e) {}
    }
    
    private static void organizeFolder() {       
        File file = new File(System.getProperty("user.dir") + "\\others\\Day25_WhereToEat.txt");
        file.delete();
    
        File file1 = new File(System.getProperty("user.dir") + "\\others\\tmp.txt");
        File file2 = new File(System.getProperty("user.dir") + "\\others\\Day25_WhereToEat.txt");
        file1.renameTo(file2);
    }
    

    reply permalink

  • Carlos - 10 years, 8 months ago

    The method pickPlace() is actually wrong, since i'm going for static variables, it should clear whatever was remaining on the other variables

    public static void pickPlace() {
        for(int i=0; i<places.size(); i++) {
            places.remove(i);
        }
        rng = new Random();
        content = "";
        rndN = 0;
    
        getPlaces();
        chooseNewPlace();
        placeNewContent();
        organizeFolder();
    }
    

    Also, the file should look somehting like this for this solution (they have '/n's): There; The other one; Everywhere; Xing Xong; Kunt Pao; Lagostas; Doritos; The other one;

    reply permalink

  • Jt - 10 years, 8 months ago

    C#, also I learned that I don't know how to spell restaurant.

    namespace ProblemOtd20140408
    {
      using System;
      using System.Collections.Generic;
      using System.IO;
    
      class Program
      {
        static void Main(string[] args)
        {
          string fileLocation;
          if (args.Length == 0)
          {
            Console.WriteLine("You must specify a file with your restaurant choices.");
            fileLocation = Console.ReadLine();
          }
          else
          {
            fileLocation = args[0];
          }
    
          FileInfo fileInfo = new FileInfo(fileLocation);
    
          if (!fileInfo.Exists)
          {
            Console.WriteLine("The file you specified does not exist.");
          }
          else
          {
            List<Restaurant> choices = GetChoices(fileInfo);
            if (choices.Count == 0)
            {
              Console.WriteLine("The file you specified does not contain any restaurants.");
            }
            else
            {
              Restaurant randomRestaurant = GetRandomRestaurant(choices);
              while (randomRestaurant.AteAtLastTime)
              { // If we ate at the chosen restaurant last time get another random choice
                randomRestaurant = GetRandomRestaurant(choices);
              }
    
              Console.WriteLine("You should eat at " + randomRestaurant.Name);
              WriteResults(fileInfo, choices, randomRestaurant);
            }
          }
    
          Console.WriteLine("Finished, press enter to exit");
          Console.ReadLine();
        }
    
        private static List<Restaurant> GetChoices(FileInfo file)
        {
          List<Restaurant> choices = new List<Restaurant>();
          StreamReader streamReader = new StreamReader(file.FullName);
          while (!streamReader.EndOfStream)
          {
            string choice = streamReader.ReadLine();
            choices.Add(choice.EndsWith("*") ? new Restaurant(choice.Substring(0, choice.Length - 1), true) : new Restaurant(choice));
          }
          streamReader.Close();
    
          return choices;
        }
    
        private static Restaurant GetRandomRestaurant(List<Restaurant> choices)
        {
          Random random = new Random();
          return choices[random.Next(0, choices.Count)];
        }
    
        private static void WriteResults(FileInfo file, List<Restaurant> choices, Restaurant chosenRestaurant)
        {
          StreamWriter streamWriter = new StreamWriter(file.FullName);
          foreach (Restaurant choice in choices)
          {
            streamWriter.WriteLine(choice.Name + (choice == chosenRestaurant ? "*" : ""));
          }
          streamWriter.Flush();
          streamWriter.Close();
        }
    
        private class Restaurant
        {
          public Restaurant(string name)
          {
            this.Name = name;
            this.AteAtLastTime = false;
          }
    
          public Restaurant(string name, bool ateAtLastTime)
          {
            this.Name = name;
            this.AteAtLastTime = ateAtLastTime;
          }
    
          public string Name { get; private set; }
          public bool AteAtLastTime { get; private set; }
        }
      }
    }
    

    reply permalink

  • Mre64 - 10 years, 6 months ago

    I cannot spell "definitely" without spell check for the life of me. No idea why its such a hard word for me...

    reply permalink

  • Hueho - 10 years, 8 months ago

    Over-engineering to the max (Ruby)

    require 'yaml'
    require 'optparse'
    
    $EATS_FILE = 'eats.yml'
    
    class Eats
    
      class NoPlaceError < RuntimeError
        def initialize
          super "There is no place to eat yet!"
        end
      end
    
      def initialize
        dump = YAML.load_file($EATS_FILE)
        @places = dump[:places]
        @last = dump[:last]
      end
    
      def add_place(place)
        @places << place
      end
    
      def remove_place(place)
        @places.delete place
      end
    
      def choose_place
        if @places.empty?
          raise NoPlaceError.new
        end
    
        if @places.size == 1
          return @places.to_a.first
        end
    
        loop do
          if (it = @places.sample) != @last
            return (@last = it)
          end
        end
      end
    
      def to_h
        { places: @places, last: @last }
      end
    
      def save
        File.open($EATS_FILE, 'w') do |f|
          YAML.dump self.to_h, f
        end
      end
    
    end
    
    module App
      module_function
    
      CLEAN_HASH = { places: [], last: nil }
    
      def init
        File.open($EATS_FILE, 'w') do |f|
          YAML.dump CLEAN_HASH, f
        end
      end
    
      def get_eat
        begin
          store = Eats.new
          place = store.choose_place
          store.save
          puts "Today you eat at #{place}!"
        rescue Eats::NoPlaceError => e
          puts e.message
        end
      end
    
      def add_eat(place)
        store = Eats.new
        store.add_place place
        store.save
      end
    
      def remove_eat(place)
        store = Eats.new
        store.remove_place place
        store.save
      end
    
      def main
        App.init unless File.exists? $EATS_FILE
    
        if ARGV.empty?
          App.get_eat
          exit
        end
    
        OptionParser.new do |opts|
          opts.banner = 'Usage: eats.rb [options]'
    
          opts.on '--add PLACE', 'Adds a new place to eat' do |place|
            App.add_eat place
            exit
          end
    
          opts.on '--remove PLACE', 'Removes a place from the eats list' do |place|
            App.remove_eat place
            exit
          end
    
          opts.on '--get', 'Shows where to eat today' do
            App.get_eat
            exit
          end
    
          opts.on '--clean', 'Cleans eats file' do
            App.init
            exit
          end
    
          opts.on_tail '--help', 'Shows this help' do
            puts opts
            exit
          end
    
        end.parse!
    
      end
    end
    
    App.main
    

    reply permalink

  • Pegleg - 10 years, 8 months ago

    Simple text file input/output seperated by whitespace, I.E Ruby Tuesdays 0 Chipotle 1

    import random import os import sys dictz = {} if os.stat('res.txt').st_size==0: print 'abort! file is empty' sys.exit() file = open('res.txt', 'r') for line in file: temp = line.split() dictz[temp[0]] = int(temp[1]) file.close() choice = random.choice(dictz.keys()) while dictz[choice] !=0: choice = random.choice(dictz.keys()) print 'We choose', choice, '!' file = open('res.txt', 'w') dictz[choice] = 1 for k,v in dictz.items(): if v == 1 and k != choice: v = 0 file.write(k + ' ' + str(v)+ '\n')

    reply permalink

  • Pegleg - 10 years, 8 months ago

    My apologizes vim copy and paste... How do I clean up the formatting :-X also this was in Python

    reply permalink

  • Max Burstein - 10 years, 8 months ago

    The site uses github flavored markdown so you can just post your code like this https://help.github.com/articles/github-flavored-markdown#fenced-code-blocks

    The preview comment button will also allow you to see how it will be formatted before you post.

    reply permalink

  • Pegleg - 10 years, 8 months ago

    import random
    import os
    import sys
    dictz = {}
    if os.stat('res.txt').st_size==0:
            print 'abort! file is empty'
            sys.exit()
    file = open('res.txt', 'r')
    for line in file:
            temp = line.split()
            dictz[temp[0]] = int(temp[1])
    file.close()
    choice = random.choice(dictz.keys())
    while dictz[choice] !=0:
            choice = random.choice(dictz.keys())
    print 'We choose', choice, '!'
    file = open('res.txt', 'w')
    dictz[choice] = 1
    for k,v in dictz.items():
            if v == 1 and k != choice:
                    v = 0
            file.write(k + ' ' + str(v)+ '\n')
    
    

    FIXED, bahaha thanks! I'll be better next time

    reply permalink

  • Walker Crouse - 10 years, 8 months ago

    So here's something a bit different. I built this Java program with a Java wrapper around Google Places API that I wrote a few months ago.

    It picks takes a zip-code, radius (m), and max and min price to select restaurants and then picks a random one from that. Every time one is picked it is put in a text file and compared to make sure two places cannot be picked multiple times in a row.

    package me.windwaker.potd;
    
    import me.windwaker.places.GooglePlaces;
    import me.windwaker.places.Place;
    import org.apache.commons.io.IOUtils;
    import org.apache.http.HttpException;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.json.JSONObject;
    
    import java.io.*;
    import java.net.URISyntaxException;
    import java.util.List;
    import java.util.Random;
    import java.util.Scanner;
    
    import static me.windwaker.places.GooglePlaces.MAXIMUM_RESULTS;
    import static me.windwaker.places.GooglePlaces.Param;
    
    public class WhereToEat {
        private static final String API_KEY = "********";
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            // initialize client
            GooglePlaces client = new GooglePlaces(API_KEY);
            client.setSensorEnabled(false);
    
            while (true) {
                // get zip code
                System.out.print("Zip code: ");
                String zip = scanner.next();
    
                // get lat lng of zip
                double lat = 0, lng = 0;
                try {
                    String url = String.format("https://maps.googleapis.com/maps/api/geocode/json?components=postal_code:%s" +
                            "&sensor=false&key=%s", zip, API_KEY);
                    HttpGet get = new HttpGet(url);
                    String rawJson = readString(client.getHttpClient().execute(get));
                    JSONObject json = new JSONObject(rawJson).getJSONArray("results").getJSONObject(0).getJSONObject("geometry")
                            .getJSONObject("location");
                    lat = json.getDouble("lat");
                    lng = json.getDouble("lng");
                } catch (URISyntaxException | IOException | HttpException e) {
                    e.printStackTrace();
                }
                System.out.printf("Latitude/Longitude: %f, %f\n", lat, lng);
    
                // input
                System.out.print("Radius (m): ");
                double radius = scanner.nextDouble();
                System.out.print("Minimum price (?/4): ");
                int minPrice = scanner.nextInt();
                System.out.print("Maximum price (?/4): ");
                int maxPrice = scanner.nextInt();
    
                // get nearby places
                List<Place> places =
                        client.getNearbyPlaces(lat, lng, radius, MAXIMUM_RESULTS, Param.name("types").value("restaurant"),
                                Param.name("minprice").value(minPrice), Param.name("maxprice").value(maxPrice));
    
                if (places.isEmpty()) {
                    System.out.println("No places found.");
                    break;
                }
    
                Random random = new Random();
                Place place = places.get(random.nextInt(places.size()));
    
                // dont pick a place twice
                try {
                    Scanner fs = new Scanner(new FileReader("last.place"));
                    if (fs.hasNext()) {
                        String id = fs.next();
                        while (id.equals(place.getId())) {
                            place = places.get(random.nextInt(places.size()));
                        }
                    }
                    fs.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
    
                // print the details
                place = place.getDetails();
                System.out.println("\nYou should eat at: " + place.getName());
                System.out.println("Address: " + place.getAddress());
                System.out.println("Phone #: " + place.getPhoneNumber());
                System.out.println("Rating: " + place.getRating() + "/5");
                System.out.println("Price: " + place.getPrice());
    
                // write the id to disk
                try {
                    PrintWriter writer = new PrintWriter(new FileWriter("last.place"));
                    writer.println(place.getId());
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                boolean end = false;
                while (true) {
                    System.out.print("\nTry again? (y/n): ");
                    String next = scanner.next();
                    if (next.equalsIgnoreCase("y")) {
                        break;
                    } else if (next.equalsIgnoreCase("n")) {
                        end = true;
                        break;
                    }
                }
    
                if (end) {
                    break;
                }
            }
            scanner.close();
        }
    
        private static String readString(HttpResponse response) throws IOException {
            return IOUtils.toString(response.getEntity().getContent());
        }
    }
    

    Sample Output:

    Zip code: 12345
    Latitude/Longitude: 42.814001, -73.981458
    Radius (m): 10000
    Minimum price (?/4): 0
    Maximum price (?/4): 4
    
    You should eat at: The Bier Abbey
    Address: 613 Union St, Schenectady, NY, United States
    Phone #: (518) 388-8597
    Rating: 4.3/5
    Price: NONE
    
    Try again? (y/n): y
    Zip code: 12345
    Latitude/Longitude: 42.814001, -73.981458
    Radius (m): 2345
    Minimum price (?/4): 2
    Maximum price (?/4): 3
    
    You should eat at: Greek Island
    Address: 93 W Campbell Rd, Schenectady, NY, United States
    Phone #: (518) 372-3717
    Rating: -1.0/5
    Price: MODERATE
    
    Try again? (y/n): y
    Zip code: 12345
    Latitude/Longitude: 42.814001, -73.981458
    Radius (m): 6000
    Minimum price (?/4): 4
    Maximum price (?/4): 4
    No places found.
    
    Process finished with exit code 0
    

    reply permalink

  • Mre64 - 10 years, 6 months ago

    BRILLIANT WORK !

    reply permalink

  • Karl T - 10 years, 8 months ago

    This took me about 4 hours to make (no regrets!) and I'm pretty proud of the result (even if it's way more complicated than it needs to be).

    Stores the list in a text file and stores the last-eaten-at place in a separate text file to avoid having to re-write the potentially long list each time (though this could be stored to registry if really needed).

    Has the ability to get a true random number from random.org! :D

    Feedback very much requested!

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Windows.Forms;
    
    namespace WhereToEat
    {
        internal class Program
        {
            private static void Main()
            {
                try
                {
                    string strLocationListFile = Application.StartupPath + "\\WhereToEat-List.txt";
    
                    List<string> listLocations = new List<string>();
    
                    if (!File.Exists(strLocationListFile))
                    {
                        string[] strNewList = { "Moobies", "Burger Shot", "Jackrabbit Slims",
                                              "The Restaurant at the End of Universe", "The Krusty Krab",
                                             "Mos Eisley Cantina Bar", "Guadalajara Brown Drip Gourmet Coffee" };
    
                        listLocations.AddRange(strNewList);
    
                        File.WriteAllLines(strLocationListFile, strNewList); //Make the default file
                    }
                    else
                    {
                        listLocations.AddRange(File.ReadAllLines(strLocationListFile)); //Pull all locations from file
                    }
    
                    string strLastAteFile = Application.StartupPath + "\\WhereToEat-Last.txt";
                    string strLastAte = "";
    
                    if (File.Exists(strLastAteFile))
                    {
                        strLastAte = File.ReadAllText(strLastAteFile); //Get the last location from the file
    
                        if (!string.IsNullOrEmpty(strLastAte) && listLocations.Contains(strLastAte))
                        {
                            listLocations.Remove(strLastAte); //We don't want this to be on the list
                        }
                    }
    
                    int intRandomIndex;
                    string strRandomLocation;
    
                Loop: //When they choose no, ask again with next random item
    
                    if (listLocations.Count < 1) //Once they've depleted the list
                    {
                        Console.Clear();
    
                        Console.WriteLine("You're being too picky! There are no more items on the list to choose from!");
                        Console.WriteLine();
                        Console.WriteLine("Press any key to open up the file and add more locations, or hit escape if you're too lazy.");
    
                        if (Console.ReadKey(true).Key != ConsoleKey.Escape)
                        {
                            System.Diagnostics.Process.Start(strLocationListFile); //Open the file
                        }
    
                        return;
                    }
                    else if (listLocations.Count == 1) //No need to do a random value for 0 - 0 if there's only one item xD
                    {
                        intRandomIndex = 0;
                    }
                    else
                    {
                        intRandomIndex = GetRandomNumber(listLocations.Count, true); //True: computer will pull "true" random number from internet
    
                        if (intRandomIndex < 0)
                        {
                            Console.WriteLine("An error occurred."); //Oh no!
                            Console.WriteLine();
                            Console.WriteLine("Press any key to exit.");
    
                            Console.ReadKey(true);
    
                            return;
                        }
                    }
    
                    strRandomLocation = listLocations[intRandomIndex]; //Set the randomly chosen location
    
                AskAgain: //In case they press a key that's not N or Y
    
                    Console.Clear();
    
                    if (!string.IsNullOrEmpty(strLastAte)) //If we've eaten somewhere before...
                    {
                        Console.WriteLine("You ate at " + strLastAte + " last time, so you're going to live a little" +
                            " and eat somewhere else today.");
                        Console.WriteLine();
                    }
    
                    if (listLocations.Count == 1)
                    {
                        Console.WriteLine("This is your last choice!");
                        Console.WriteLine();
                    }
    
                    Console.WriteLine("Would you like to eat at " + strRandomLocation + "? [ Y / N ]");
    
                    switch (Console.ReadKey(true).Key)
                    {
                        case ConsoleKey.N:
                            listLocations.Remove(strRandomLocation);
    
                            goto Loop; //Restart process
    
                        case ConsoleKey.Y:
                            break;
    
                        default:
                            goto AskAgain; //We don't care about this
                    }
    
                    File.WriteAllText(strLastAteFile, strRandomLocation); //Set the last place eaten at
    
                    Console.Clear();
    
                    Console.WriteLine("Congratulations, you chose to eat at " + strRandomLocation + "!");
                    Console.WriteLine();
                    Console.WriteLine("Press any key to exit and go eat!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.ToString());
                    Console.WriteLine("Press any key to exit.");
                }
    
                Console.ReadKey(true);
            }
    
            /// <summary>
            /// Returns a random number (optionally from http://random.org)
            /// </summary>
            /// <param name="intListCount">The size of the list</param>
            /// <param name="bTrueRandom">Whether or not to retrieve number from internet</param>
            /// <returns>Random number</returns>
            private static int GetRandomNumber(int intListCount, bool bTrueRandom = false)
            {
                Console.Clear();
    
                Console.WriteLine("Getting random location" + (bTrueRandom ? " from the internet" : "") + "...");
    
                int intRandomIndex = -1; //Set to -1 in case of errors
    
                if (bTrueRandom)
                {
                    try
                    {
                        //Format: http://www.random.org/integers/?num=1&min=0&max=1&col=1&base=10&format=plain&rnd=new
    
                        string sURL = "";
                        sURL += "http://www.random.org/integers/?num=1&min=0&";
                        sURL += "max=" + (intListCount - 1) + "&";
                        sURL += "col=1&base=10&format=plain&rnd=new";
    
                        WebRequest wrGETURL = WebRequest.Create(sURL); //We could use WebClient, but this is more compatible
    
                        wrGETURL.Method = "GET";
    
                        using (WebResponse response = wrGETURL.GetResponse())
                        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                        {
                            string strResponse = reader.ReadLine();
    
                            if (string.IsNullOrEmpty(strResponse))
                            {
                                throw new NullReferenceException("Response from random.org was empty.");
                            }
    
                            intRandomIndex = int.Parse(strResponse.Trim());
                        }
    
                        //Sleep for two reasons: so they have time to read the text and so they can't hit no too fast (server no gusta)
                        System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error: " + ex.ToString());
                    }
                }
                else
                {
                    Random randomNumber = new Random(Environment.TickCount); //Pseudo-random number
    
                    intRandomIndex = randomNumber.Next(0, intListCount - 1);
                }
    
                return intRandomIndex;
            }
        }
    }
    

    reply permalink

  • Mre64 - 10 years, 6 months ago

    /* Mre64 6/9/14

    "Facts are stupid things"
        -Ronald Reagan, Former U.S. President 
    

    */

    import java.util.Random; import java.io.*;

    public class FoodPicker {

    public static void main(String[] args) throws IOException {
    
        //food item array
        String[] foodList = {"burger","cheese","eggs","bread","banana","tofu","pho","more pho"};
    
        //create random number "n" to choose array location
        Random rand = new Random();
        int  n = rand.nextInt(foodList.length);
    
        //read file for previous food
        BufferedReader br = new BufferedReader(new FileReader("C:/thetextfile.txt"));
        StringBuilder sb = new StringBuilder();
        String read = br.readLine();
    
        //disallow eating at the same place twice in a row
        while(foodList[n].equals(read)){
            n = rand.nextInt(7) + 1;
        }
        //print food for the day
        System.out.println(foodPicker(foodList[n]));    
    }
    //food picker method
    public static String foodPicker(String foodList) throws IOException{
        //write the food chosen to a text file
        try {
            String str = foodList;
            File file = new File("C:/thetextfile.txt");
            FileWriter fw = new FileWriter(file);
            fw.write(str);
            fw.close();
    
        //catch exception
        } catch (IOException iox) {
    
            System.out.println("excpetion");
        }
        return foodList;
    }
    

    }

    reply permalink

Content curated by @MaxBurstein