### Install Project Dependencies Source: https://github.com/murfffi/zebra4j/blob/main/CONTRIBUTING.md Execute this command before merging changes to build and test the project. ```bash ./mvnw install ``` -------------------------------- ### Run zebra4j CLI with Docker Source: https://github.com/murfffi/zebra4j/blob/main/README.md Execute the zebra4j command-line interface using Docker for a quick and easy setup. This command pulls the latest image and displays help information. ```bash docker run --rm murfffi/zebracli --help ``` -------------------------------- ### Run Zebra4j Demo with Maven Source: https://github.com/murfffi/zebra4j/blob/main/README.md Execute this command to run a demonstration of the Zebra4j library. Requires Java 8+ JDK. ```bash ./mvnw exec:java ``` -------------------------------- ### Deploy Project Artifacts Source: https://github.com/murfffi/zebra4j/blob/main/CONTRIBUTING.md Use this command with the 'release' profile to deploy project artifacts. ```bash ./mvnw -P release deploy ``` -------------------------------- ### View Zebra4j CLI Options with Maven Source: https://github.com/murfffi/zebra4j/blob/main/README.md Use this command to display all available command-line interface options for Zebra4j. Requires Java 8+ JDK. ```bash ./mvnw exec:java '-Dexec.args=--help' ``` -------------------------------- ### Formulating and Answering Questions with `Question` Source: https://context7.com/murfffi/zebra4j/llms.txt Shows how to use the `Question` class to define and answer queries about puzzle solutions. Imports `zebra4j.*` and `java.util.*`. ```java import zebra4j.*; import java.util.Locale; import java.util.Optional; // Predefined question: "Who is the criminal?" Question predefined = Question.NAME_OF_CRIMINAL; System.out.println(predefined.describe(Locale.ENGLISH)); // "What is the name of the criminal?" // Generate a random question from an existing solution PuzzleSolution solution = new SolutionGenerator(4).generate(); Question random = Question.generate(solution); System.out.println(random.describe(Locale.ENGLISH)); // e.g.: "What pet does Ivan own?" // Answer the question Optional answer = random.answer(solution); answer.ifPresent(a -> System.out.println("Answer: " + a.description(Locale.ENGLISH))); // Answer: owns a dog // Custom question: "What pet does the person in blue clothes own?" BasicAttributeType clothes = new BasicAttributeType( org.apache.commons.collections4.SetUtils.unmodifiableSet( "is in blue clothes", "is in red clothes"), "What clothes does %s wear?", "Clothes"); BasicAttributeType pet = new BasicAttributeType( org.apache.commons.collections4.SetUtils.unmodifiableSet( "owns a dog", "owns a cat"), "What pet does %s own?", "Pet"); Question custom = new Question(clothes.findByLabel("is in blue clothes").get(), pet); System.out.println(custom.describe(Locale.ENGLISH)); // "What pet does the person who is in blue clothes own?" ``` -------------------------------- ### Run zebra4j CLI with JAR Source: https://github.com/murfffi/zebra4j/blob/main/README.md If Docker is not available, download the shaded JAR file and run the zebra4j command-line interface. This method works on any system architecture supported by Java. ```bash java -jar zebra4j-bundle.jar --help ``` -------------------------------- ### Update License File Headers Source: https://github.com/murfffi/zebra4j/blob/main/CONTRIBUTING.md Run this command after adding new files to ensure they have the correct license header. ```bash ./mvnw license:update-file-header ``` -------------------------------- ### Running Zebra4j Puzzles via CLI/Docker Source: https://context7.com/murfffi/zebra4j/llms.txt Provides commands for generating and running puzzles using the Zebra4j CLI and Docker image. Includes options for reproducible seeds. ```bash # Generate a random question puzzle (Docker, amd64 only) docker run --rm murfffi/zebracli generate # Generate with a fixed seed for reproducibility docker run --rm murfffi/zebracli generate --seed 8574845971565421814 # Run using the shaded JAR (any platform with Java) java -jar zebra4j-0.10-shaded.jar generate --seed 8574845971565421814 # Print CLI help java -jar zebra4j-0.10-shaded.jar --help # Build and run the demo via Maven wrapper ./mvnw exec:java ``` -------------------------------- ### Solve a BasicPuzzle with PuzzleSolver Source: https://context7.com/murfffi/zebra4j/llms.txt Use `PuzzleSolver` to find solutions for a `BasicPuzzle`. `solve()` returns all solutions, while `solveToStream()` provides a lazy stream for early termination. ```java import zebra4j.*; import java.util.List; import java.util.stream.Stream; BasicPuzzle puzzle = PuzzleGenerator.randomPuzzle(3); PuzzleSolver solver = new PuzzleSolver(puzzle); // Eager: collect all distinct solutions List allSolutions = solver.solve(); System.out.println("Number of solutions: " + allSolutions.size()); // 1 for generated puzzles // Lazy stream: find any solution without enumerating all PuzzleSolution first = new PuzzleSolver(puzzle).solveToStream().findAny() .orElseThrow(() -> new RuntimeException("No solution found")); // Inspect a solution: find which person has a specific attribute SolutionPerson person = first.findPerson(PersonName.TYPE.getAttributes(3).get(0)).orElse(null); if (person != null) { person.asList().forEach(attr -> System.out.println(attr.description(java.util.Locale.ENGLISH))); } ``` -------------------------------- ### Sample Puzzle 3: Pet of Person in Green Clothes Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This sample defines facts about pets, clothing colors, house adjacency, and specific person/house assignments, then asks about the pet of the person in green clothes. The seed is provided for replication. ```text Facts: Any person either owns a hamster or owns a cat or owns a zebra or owns a snake. People's names are Theodora, Ivan, Peter, Elena. Any person either is in red clothes or is in green clothes or is in blue clothes or is in yellow clothes. They live in 4 adjacent houses. The person who is in blue clothes is not the person who owns a snake. The person who is is in red clothes lives next door from the one who is is in blue clothes. The person who is at house 3 is not the person who is in green clothes. The person who is at house 2 is not the person who is in blue clothes. Elena is at house 3. The person who is at house 2 also owns a hamster. The person who is in blue clothes is not the person who owns a cat. Elena owns a snake. The person who is at house 1 is not the person who is in yellow clothes. Question: What pet does the person who is in green clothes own? Answer options: owns a hamster, owns a cat, owns a zebra, owns a snake Answer: owns a cat Seed: 5094510298122990809 ``` -------------------------------- ### Generate Puzzle with Docker Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This command generates a puzzle using the zebra4j Docker image. Use the provided seed to replicate the exact puzzle. ```sh docker run --rm murfffi/zebracli:0.9 generate --seed 9093154172883354085 ``` -------------------------------- ### Generate and Solve a BasicPuzzle Source: https://context7.com/murfffi/zebra4j/llms.txt Generates a random BasicPuzzle for a specified number of people, solves it, and prints the puzzle constraints and solution details in English. Assumes default attribute types and fact types. ```java import zebra4j.*; import java.util.List; import java.util.Locale; // Generate a puzzle for 4 people, then solve and print it BasicPuzzle puzzle = PuzzleGenerator.randomPuzzle(4); PuzzleSolver solver = new PuzzleSolver(puzzle); List solutions = solver.solve(); // solutions always has exactly 1 element for generator-produced puzzles PuzzleSolution solution = solutions.get(0); // Describe the puzzle constraints in English puzzle.describeConstraints(Locale.ENGLISH).forEach(System.out::println); // e.g.: // People's names are Ivan, Elena, Peter, Theodora. // One person is a criminal. // Any person either is in yellow clothes or ... // They live in 4 adjacent houses. // Ivan is at house 2. // The person who is in blue clothes also is the criminal. // ... // Describe the solution String[][] described = solution.describe(Locale.ENGLISH); for (String[] person : described) { System.out.println(String.join(", ", person)); } // e.g.: Ivan, at house 2, is in blue clothes, is the criminal, owns a zebra ``` -------------------------------- ### Sample Puzzle 1: Person's House Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This sample defines facts about people, their pets, clothes, and houses, then asks for the house of the person in yellow clothes. The seed is provided for replication. ```text Facts: Any person either owns a zebra or owns a cat or owns a hamster or owns a snake. People's names are Ivan, Theodora, Peter, Elena. One person is a criminal. Any person either is in yellow clothes or is in green clothes or is in red clothes or is in blue clothes. They live in 4 adjacent houses. Peter is at house 2. Peter isn't the person who is in yellow clothes. Theodora isn't the person who owns a hamster. Ivan isn't the person who owns a cat. Theodora is in green clothes. The person who is at house 4 is not the person who owns a cat. The person who is at house 2 is not the person who is the criminal. The person who is at house 1 is not the person who owns a hamster. Ivan isn't the person who owns a snake. The person who is in blue clothes also is the criminal. The person who is the criminal also owns a snake. Elena is at house 3. Question: Which is the house of the person who is in yellow clothes? Answer options: is at house 4, is at house 1, is at house 2, is at house 3 Answer: is at house 4 Seed: 8574845971565421814 ``` -------------------------------- ### Sample Puzzle 4: Peter's House Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This sample defines facts about pets, clothing colors, house adjacency, and relative positions, then asks for Peter's house. The seed is provided for replication. ```text Facts: Any person either owns a cat or owns a zebra or owns a hamster or owns a snake. People's names are Theodora, Elena, Ivan, Peter. Any person either is in green clothes or is in blue clothes or is in yellow clothes or is in red clothes. They live in 4 adjacent houses. Elena owns a zebra. Peter isn't the person who is in green clothes. The person who is is in green clothes lives next door from the one who is is in yellow clothes. The person who is is in green clothes lives next door from the one who is is in blue clothes. The person who is at house 4 also owns a zebra. Elena lives 2 doors away from Ivan. Ivan isn't the person who is in green clothes. Question: Which is the house of Peter? Answer options: is at house 3, is at house 4, is at house 2, is at house 1 Answer: is at house 1 Seed: 6877092184460536910 ``` -------------------------------- ### Generate and Solve a QuestionPuzzle Source: https://context7.com/murfffi/zebra4j/llms.txt Generates a QuestionPuzzle with a random question and a unique answer. It then prints the puzzle's constraints, the question in natural language, and the single attribute answer after solving. ```java import zebra4j.*; // Generate a question puzzle for 4 people QuestionPuzzle qPuzzle = QuestionPuzzleGenerator.randomPuzzle(4); // The embedded BasicPuzzle contains the clue facts qPuzzle.getBasicPuzzle().describeConstraints(Locale.ENGLISH).forEach(System.out::println); // The question in natural language System.out.println(qPuzzle.getQuestion().describe(Locale.ENGLISH)); // e.g.: "What pet does the person who is in blue clothes own?" // Solve: returns the single answer attribute QuestionPuzzleSolver qSolver = new QuestionPuzzleSolver(qPuzzle); Attribute answer = qSolver.solveSingle(); System.out.println(answer.description(Locale.ENGLISH)); // e.g.: "owns a zebra" ``` -------------------------------- ### Sample Puzzle 2: Theodora's Pet Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This sample defines facts about pets, criminal status, names, and clothing colors, then asks about Theodora's pet. The seed is provided for replication. ```text Facts: Any person either owns a hamster or owns a snake or owns a cat or owns a zebra. One person is a criminal. People's names are Theodora, Peter, Elena, Ivan. Any person either is in green clothes or is in red clothes or is in blue clothes or is in yellow clothes. The person who is in red clothes also owns a snake. The person who is the criminal also owns a cat. Ivan isn't the person who is in blue clothes. The person who is in blue clothes also owns a cat. Theodora isn't the person who is in red clothes. Theodora isn't the person who is the criminal. Ivan isn't the person who is in red clothes. Ivan isn't the person who owns a hamster. Question: What pet does Theodora own? Answer options: owns a hamster, owns a snake, owns a cat, owns a zebra Answer: owns a hamster Seed: 4574246929601235406 ``` -------------------------------- ### Generate Puzzle with Uber Jar Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This command generates a puzzle using the zebra4j uber jar. Use the provided seed to replicate the exact puzzle. ```sh java -jar zebra4j-0.9-shaded.jar generate --seed 9093154172883354085 ``` -------------------------------- ### Add zebra4j Dependency to Maven Project Source: https://github.com/murfffi/zebra4j/blob/main/README.md Include this dependency in your Maven project's pom.xml to use the zebra4j library. It's recommended to replace 'RELEASE' with a specific version to avoid unexpected breaking changes. ```xml ... ... io.github.murfffi zebra4j RELEASE ... ``` ``` -------------------------------- ### Define Custom Attribute Type with BasicAttributeType Source: https://context7.com/murfffi/zebra4j/llms.txt Introduce domain-specific attributes like 'Job' using BasicAttributeType. This is the simplest way to add custom attributes with plain string labels and a question pattern. ```java import zebra4j.*; import org.apache.commons.collections4.SetUtils; // Define a "Job" attribute type with 4 possible values BasicAttributeType job = new BasicAttributeType( SetUtils.unmodifiableSet("is a doctor", "is a teacher", "is an engineer", "is an artist"), "What is the job of %s?", "Job"); // Retrieve a specific attribute by label zebra4j.Attribute doctor = job.findByLabel("is a doctor").get(); System.out.println(doctor.description(java.util.Locale.ENGLISH)); // is a doctor // Use in a puzzle builder alongside built-in types PuzzleBuilder builder = new PuzzleBuilder(); builder.addSet(AtHouse.TYPE.getAttributes(4).toArray(new AtHouse[]{})); builder.addSet(PersonName.TYPE.getAttributes(4).toArray(new zebra4j.Attribute[]{})); // add the full set of job attributes builder.addSet(job.getAttributes(4).toArray(new zebra4j.Attribute[]{})); // Describe the set in natural language String setDesc = job.describeSet(job.getAttributes(4), java.util.Locale.ENGLISH); System.out.println(setDesc); // e.g.: "Any person either is a doctor or is a teacher or is an engineer or is an artist." ``` -------------------------------- ### Built-in Fact Types: BothTrue, Different, NearbyHouse Source: https://context7.com/murfffi/zebra4j/llms.txt Demonstrates the usage of BothTrue, Different, and NearbyHouse fact types for defining relationships in puzzles. Requires importing zebra4j.* and zebra4j.fact.*. ```java import zebra4j.*; import zebra4j.fact.*; import java.util.Locale; // BothTrue: two attributes belong to the same person // "The person who owns a cat is in red clothes." BasicAttributeType clothes = new BasicAttributeType( org.apache.commons.collections4.SetUtils.unmodifiableSet( "is in red clothes", "is in blue clothes", "is in green clothes"), "What clothes does %s wear?", "Clothes"); BasicAttributeType pet = new BasicAttributeType( org.apache.commons.collections4.SetUtils.unmodifiableSet( "owns a cat", "owns a dog", "owns a bird"), "What pet does %s own?", "Pet"); Fact bothTrue = new BothTrue( pet.findByLabel("owns a cat").get(), clothes.findByLabel("is in red clothes").get()); System.out.println(bothTrue.describe(Locale.ENGLISH)); // "The person who owns a cat also is in red clothes." // Different: two attributes belong to different people // "The person who owns a dog is NOT in red clothes." Fact different = new Different( pet.findByLabel("owns a dog").get(), clothes.findByLabel("is in red clothes").get()); System.out.println(different.describe(Locale.ENGLISH)); // "The person who owns a dog is not the person who is in red clothes." // NearbyHouse: two attributes belong to people whose houses are a given distance apart // "The person who owns a cat lives next door to the person in blue clothes." PuzzleBuilder builder = new PuzzleBuilder(); builder.addSet(AtHouse.TYPE.getAttributes(3).toArray(new AtHouse[]{})); builder.addSet(pet.getAttributes(3).toArray(new Attribute[]{})); builder.addSet(clothes.getAttributes(3).toArray(new Attribute[]{})); Fact nearby = new NearbyHouse(1, pet.findByLabel("owns a cat").get(), clothes.findByLabel("is in blue clothes").get()); System.out.println(nearby.describe(Locale.ENGLISH)); // "The person who owns a cat lives next door from the one who is in blue clothes." builder.addFact(nearby); ``` -------------------------------- ### Solve a QuestionPuzzle with QuestionPuzzleSolver Source: https://context7.com/murfffi/zebra4j/llms.txt Use `QuestionPuzzleSolver` for puzzles with a single question to efficiently project the solution onto the answer attribute. It avoids computing full person-attribute assignments. ```java import zebra4j.*; import java.util.Set; QuestionPuzzle qPuzzle = QuestionPuzzleGenerator.randomPuzzle(4); QuestionPuzzleSolver solver = new QuestionPuzzleSolver(qPuzzle); // Returns the set of all possible answers (should be size 1 for generated puzzles) Set answers = solver.solve(); System.out.println("Possible answers: " + answers.size()); // 1 // Convenience method for single-answer puzzles Attribute answer = solver.solveSingle(); System.out.println(answer.description(java.util.Locale.ENGLISH)); // Lazy stream of answers solver.solveToStream().forEach(a -> System.out.println(a.description(java.util.Locale.ENGLISH))); ``` -------------------------------- ### Manually Construct a Puzzle with PuzzleBuilder Source: https://context7.com/murfffi/zebra4j/llms.txt Use `PuzzleBuilder` to define custom attribute types and facts for hand-crafting puzzles. It validates attribute sets and facts as they are added to prevent inconsistencies. ```java import zebra4j.*; import zebra4j.fact.*; import java.util.List; import java.util.Locale; PuzzleBuilder builder = new PuzzleBuilder(); // Add house positions 1–5 builder.addSet(AtHouse.TYPE.getAttributes(5).toArray(new AtHouse[]{})); // Add custom attribute types using labels (no ResourceBundle needed) BasicAttributeType nationality = builder.addSet("Nationality", "is an Englishman", "is a Spaniard", "is Ukrainian", "is Norwegian", "is Japanese"); BasicAttributeType beverage = builder.addSet("Beverage", "drinks coffee", "drinks tea", "drinks milk", "drinks water", "drinks orange juice"); BasicAttributeType pet = builder.addSet("Pet", "owns a zebra", "owns snails", "owns a dog", "owns a horse", "owns a fox"); // Add clue facts // "The Englishman lives in the red house" -> both attributes belong to the same person BasicAttributeType houseColor = builder.addSet("House color", "lives in the red house", "lives in the green house", "lives in the yellow house", "lives in the blue house", "lives in the ivory house"); builder.addFact(new BothTrue( nationality.findByLabel("is an Englishman").get(), houseColor.findByLabel("lives in the red house").get())); // "The Norwegian lives in the first house" builder.addFact(new BothTrue(nationality.findByLabel("is Norwegian").get(), new AtHouse(1))); // "The green house is next to the ivory house" builder.addFact(new NearbyHouse(1, houseColor.findByLabel("lives in the green house").get(), houseColor.findByLabel("lives in the ivory house").get())); BasicPuzzle puzzle = builder.build(); // Solve PuzzleSolution solution = new PuzzleSolver(puzzle).solve().get(0); // Answer specific questions Question whoOwnsZebra = new Question(pet.findByLabel("owns a zebra").get(), nationality); System.out.println("Who owns the zebra? " + whoOwnsZebra.answer(solution).get().description(Locale.ENGLISH)); // e.g.: Who owns the zebra? is Japanese ``` -------------------------------- ### Add zebra4j Maven Dependency Source: https://context7.com/murfffi/zebra4j/llms.txt Include this dependency in your Maven project to use the zebra4j library. Replace '0.10' with the latest version available on Maven Central. ```xml io.github.murfffi zebra4j 0.10 ``` -------------------------------- ### Generate Custom QuestionPuzzle with Specific Attribute Types Source: https://context7.com/murfffi/zebra4j/llms.txt Manually create QuestionPuzzleGenerator when you need a puzzle using only a subset of built-in or custom attribute types. This involves creating a SolutionGenerator first. ```java import zebra4j.*; import zebra4j.fact.*; import org.apache.commons.collections4.SetUtils; import java.util.Set; // Puzzle uses only PET, NAME, AT_HOUSE attributes Set types = SetUtils.unmodifiableSet( Attributes.PET, Attributes.NAME, Attributes.AT_HOUSE); int numPeople = 4; PuzzleSolution solution = new SolutionGenerator(types, numPeople, new zebra4j.util.JDKRandom()).generate(); // Pick a random question about the solution Question question = Question.generate(solution); System.out.println("Question: " + question.describe(java.util.Locale.ENGLISH)); // Generate the puzzle with all default fact types QuestionPuzzleGenerator generator = new QuestionPuzzleGenerator( question, solution, AbstractPuzzleGenerator.DEFAULT_FACT_TYPES); QuestionPuzzle puzzle = generator.generate(); // Solve Attribute answer = new QuestionPuzzleSolver(puzzle).solveSingle(); System.out.println("Answer: " + answer.description(java.util.Locale.ENGLISH)); ``` -------------------------------- ### PuzzleGenerator.randomPuzzle(int numPeople) Source: https://context7.com/murfffi/zebra4j/llms.txt Generates a fully random BasicPuzzle for a specified number of people. The puzzle is guaranteed to have exactly one solution and uses default attribute types and fact types. ```APIDOC ## PuzzleGenerator.randomPuzzle(int numPeople) — Generate a random BasicPuzzle Generates a fully random `BasicPuzzle` using default attribute types (`NAME`, `AT_HOUSE`, `CLOTHES`, `CRIMINAL`, `PET`) and all three built-in fact types (`BothTrue`, `Different`, `NearbyHouse`). The returned puzzle is guaranteed to have exactly one solution. ```java import zebra4j.*; import java.util.List; import java.util.Locale; // Generate a puzzle for 4 people, then solve and print it BasicPuzzle puzzle = PuzzleGenerator.randomPuzzle(4); PuzzleSolver solver = new PuzzleSolver(puzzle); List solutions = solver.solve(); // solutions always has exactly 1 element for generator-produced puzzles PuzzleSolution solution = solutions.get(0); // Describe the puzzle constraints in English puzzle.describeConstraints(Locale.ENGLISH).forEach(System.out::println); // e.g.: // People's names are Ivan, Elena, Peter, Theodora. // One person is a criminal. // Any person either is in yellow clothes or ... // They live in 4 adjacent houses. // Ivan is at house 2. // The person who is in blue clothes also is the criminal. // ... // Describe the solution String[][] described = solution.describe(Locale.ENGLISH); for (String[] person : described) { System.out.println(String.join(", ", person)); } // e.g.: Ivan, at house 2, is in blue clothes, is the criminal, owns a zebra ``` ``` -------------------------------- ### Sample Puzzle 5: Person in Yellow Clothes Source: https://github.com/murfffi/zebra4j/blob/main/SAMPLES.md This sample defines facts about criminal status, clothing colors, house adjacency, and specific person/house assignments, then asks who is in yellow clothes. The seed is provided for replication. ```text Facts: People's names are Theodora, Peter, Ivan, Elena. One person is a criminal. Any person either is in green clothes or is in blue clothes or is in yellow clothes or is in red clothes. They live in 4 adjacent houses. Ivan is at house 2. The person who is at house 4 is not the person who is in yellow clothes. The person who is in yellow clothes is not the person who is the criminal. The person who is is in green clothes lives 2 doors away from the one who is is in blue clothes. The person who is is in green clothes lives next door from the one who is is in red clothes. The person who is at house 1 also is the criminal. The person who is at house 2 is not the person who is in green clothes. Question: Who is in yellow clothes? Answer options: Theodora, Peter, Ivan, Elena Answer: Ivan Seed: 2603189112643104537 ``` -------------------------------- ### Generate Random Solution with SolutionGenerator Source: https://context7.com/murfffi/zebra4j/llms.txt Use SolutionGenerator to create a random full assignment of attributes to people. This is useful for seeding puzzle generators with custom attribute selections. ```java import zebra4j.*; import org.apache.commons.collections4.SetUtils; import java.util.Set; // Use only three attribute types (no clothes, no criminal) Set attributeTypes = SetUtils.unmodifiableSet( Attributes.PET, Attributes.NAME, Attributes.AT_HOUSE); SolutionGenerator solutionGen = new SolutionGenerator(attributeTypes, 3, new zebra4j.util.JDKRandom()); PuzzleSolution solution = solutionGen.generate(); // Inspect the solution solution.getPeople().forEach(person -> System.out.println(person.asList().stream() .map(a -> a.description(java.util.Locale.ENGLISH)) .reduce((a, b) -> a + ", " + b).orElse(""))); // e.g.: Ivan, at house 1, owns a dog // Elena, at house 3, owns a cat // Peter, at house 2, owns a zebra ``` -------------------------------- ### QuestionPuzzleGenerator.randomPuzzle(int numPeople) Source: https://context7.com/murfffi/zebra4j/llms.txt Generates a QuestionPuzzle with a random question and a unique answer for a specified number of people. Facts that would directly reveal the answer are excluded to ensure the puzzle is non-trivial. ```APIDOC ## QuestionPuzzleGenerator.randomPuzzle(int numPeople) — Generate a random QuestionPuzzle Generates a `QuestionPuzzle` with a random question (e.g. "What pet does the criminal own?") and a unique answer. Facts that would directly reveal the answer are excluded, making the puzzle non-trivial. ```java import zebra4j.*; // Generate a question puzzle for 4 people QuestionPuzzle qPuzzle = QuestionPuzzleGenerator.randomPuzzle(4); // The embedded BasicPuzzle contains the clue facts qPuzzle.getBasicPuzzle().describeConstraints(Locale.ENGLISH).forEach(System.out::println); // The question in natural language System.out.println(qPuzzle.getQuestion().describe(Locale.ENGLISH)); // e.g.: "What pet does the person who is in blue clothes own?" // Solve: returns the single answer attribute QuestionPuzzleSolver qSolver = new QuestionPuzzleSolver(qPuzzle); Attribute answer = qSolver.solveSingle(); System.out.println(answer.description(Locale.ENGLISH)); // e.g.: "owns a zebra" ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.