From cfa48663e22e018e6d9a1ee362723b5ab00803bb Mon Sep 17 00:00:00 2001 From: Oshgnacknak Date: Sun, 16 Mar 2025 16:45:18 +0100 Subject: [PATCH] Get new things --- .idea/.gitignore | 5 + .idea/misc.xml | 7 + H00/build.gradle.kts | 9 +- H00/src/main/java/h00/Main.java | 84 +- H01/src/main/java/h01/BlueGhost.java | 4 +- H01/src/main/java/h01/FuckBot.java | 72 + H01/src/main/java/h01/OrangeGhost.java | 17 +- H01/src/main/java/h01/Pacman.java | 17 +- H01/src/main/java/h01/PinkGhost.java | 19 +- H01/src/main/java/h01/RedGhost.java | 9 +- H02/src/main/java/h02/FourWins.java | 85 +- H02/src/main/java/h02/Main.java | 14 +- .../java/h02/OneDimensionalArrayStuff.java | 26 +- .../java/h02/TwoDimensionalArrayStuff.java | 18 +- H03/src/main/java/h03/Main.java | 36 + H03/src/main/java/h03/RobotsChallenge.java | 65 + .../java/h03/robots/DoublePowerRobot.java | 27 + .../main/java/h03/robots/HackingRobot.java | 62 + .../main/java/h03/robots/MovementType.java | 5 + .../main/java/h03/robots/VersatileRobot.java | 36 + H04/src/main/java/h04/GameController.java | 6 +- H04/src/main/java/h04/chesspieces/Bishop.java | 13 +- .../main/java/h04/chesspieces/ChessPiece.java | 5 + H04/src/main/java/h04/chesspieces/King.java | 78 + H04/src/main/java/h04/chesspieces/Knight.java | 5 +- H04/src/main/java/h04/chesspieces/Pawn.java | 7 +- H04/src/main/java/h04/chesspieces/Queen.java | 17 +- H04/src/main/java/h04/chesspieces/Rook.java | 13 +- .../main/java/h04/movement/DiagonalMover.java | 53 + .../main/java/h04/movement/MoveStrategy.java | 8 + .../java/h04/movement/OrthogonalMover.java | 53 + .../h04/movement/TeleportingMoveStrategy.java | 11 + .../h04/movement/WalkingMoveStrategy.java | 40 + .../h04/template/GameControllerTemplate.java | 15 +- H05/src/main/java/h05/Airspace.java | 22 +- H05/src/main/java/h05/CargoPlane.java | 30 + H05/src/main/java/h05/CarriesCargo.java | 10 + H05/src/main/java/h05/CarriesPassengers.java | 10 + H05/src/main/java/h05/CombinedPlane.java | 53 + H05/src/main/java/h05/Flying.java | 6 + H05/src/main/java/h05/FuelType.java | 18 + H05/src/main/java/h05/Main.java | 45 + H05/src/main/java/h05/PassengerPlane.java | 36 + H05/src/main/java/h05/Plane.java | 80 + H05/src/main/java/h05/Refuelling.java | 6 + H05/src/main/java/h05/Runway.java | 31 + H05/src/main/java/h05/Tank.java | 22 + H05/src/main/java/h05/TankerPlane.java | 35 + H05/src/main/java/h05/WeatherBalloon.java | 25 + H07/src/main/java/h07/Main.java | 66 - .../java/h07/NumberExpressionFactory.java | 65 - .../main/java/h07/peano/NaturalNumber.java | 17 - .../peano/PeanoNumberExpressionFactory.java | 35 - H07/src/main/java/h07/peano/Successor.java | 20 - H07/src/main/java/h07/peano/Zero.java | 14 - {H07 => H08}/.editorconfig | 0 {H07 => H08}/.gitignore | 0 {H07 => H08}/README.md | 2 +- {H07 => H08}/build.gradle.kts | 6 +- {H07 => H08}/gradle/libs.versions.toml | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 {H07 => H08}/gradlew | 0 {H07 => H08}/gradlew.bat | 0 {H07 => H08}/settings.gradle.kts | 2 +- H08/src/main/java/h08/Airport.java | 114 + H08/src/main/java/h08/Booking.java | 97 + H08/src/main/java/h08/BookingManagement.java | 93 + H08/src/main/java/h08/Flight.java | 146 + H08/src/main/java/h08/FlightManagement.java | 106 + H08/src/main/java/h08/Main.java | 15 + H08/src/main/java/h08/Passenger.java | 111 + .../src/test/java/h08}/ExampleJUnitTest.java | 2 +- {solution/H07 => H09}/.editorconfig | 0 H09/.gitignore | 88 + {solution/H07 => H09}/README.md | 2 +- H09/build.gradle.kts | 33 + H09/gradle/libs.versions.toml | 2 + H09/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes H09/gradle/wrapper/gradle-wrapper.properties | 7 + H09/gradlew | 249 + H09/gradlew.bat | 92 + H09/settings.gradle.kts | 11 + .../java/h09/EnclosureTestPublic.java | 149 + .../java/h09/H09_RubricProviderPublic.java | 152 + .../graderPublic/java/h09/H09_TestUtils.java | 689 + .../java/h09/ReflectionUtils.java | 191 + .../java/h09/StackOfObjectsTestPublic.java | 101 + .../java/h09/WaterEnclosureTestPublic.java | 140 + H09/src/main/java/h09/Enclosure.java | 119 + H09/src/main/java/h09/GroundEnclosure.java | 40 + H09/src/main/java/h09/Main.java | 15 + H09/src/main/java/h09/StackOfObjects.java | 90 + H09/src/main/java/h09/WaterEnclosure.java | 43 + H09/src/main/java/h09/abilities/Flies.java | 18 + H09/src/main/java/h09/abilities/Swims.java | 36 + H09/src/main/java/h09/abilities/Walks.java | 11 + H09/src/main/java/h09/animals/Animal.java | 71 + H09/src/main/java/h09/animals/ClownFish.java | 14 + H09/src/main/java/h09/animals/Fish.java | 34 + H09/src/main/java/h09/animals/FlyingFish.java | 63 + .../main/java/h09/animals/JugglingLion.java | 33 + .../main/java/h09/animals/KingPenguin.java | 14 + H09/src/main/java/h09/animals/Lion.java | 23 + H09/src/main/java/h09/animals/Penguin.java | 56 + H09/src/main/java/h09/animals/Turtle.java | 52 + H09/src/test/java/h09/EnclosureTest.java | 25 + H09/src/test/java/h09/ExampleJUnitTest.java | 74 + H09/src/test/java/h09/ExampleZooTest.java | 66 + {solution/H07 => H09}/version | 0 H10/.editorconfig | 12 + H10/.gitignore | 86 + H10/README.md | 4 + H10/build.gradle.kts | 31 + H10/gradle/libs.versions.toml | 2 + H10/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes .../gradle/wrapper/gradle-wrapper.properties | 0 H10/gradlew | 249 + H10/gradlew.bat | 92 + H10/settings.gradle.kts | 10 + H10/src/graderPublic/java/h10/CardGames.java | 49 + .../java/h10/DoublyLinkedLists.java | 35 + .../java/h10/H10_1_1_TestsPublic.java | 88 + .../java/h10/H10_1_4_TestsPublic.java | 48 + .../java/h10/H10_1_CountSkipCards_Tests.java | 90 + .../java/h10/H10_2_1_TestsPublic.java | 65 + .../java/h10/H10_2_2_TestsPublic.java | 66 + .../java/h10/H10_2_3_TestsPublic.java | 126 + .../java/h10/H10_2_4_TestsPublic.java | 130 + .../java/h10/H10_2_5_TestsPublic.java | 66 + .../java/h10/H10_3_1_TestsPublic.java | 156 + .../java/h10/H10_3_3_TestsPublic.java | 206 + .../java/h10/H10_RubricProviderPublic.java | 18 + .../graderPublic/java/h10/JsonConverters.java | 107 + .../java/h10/assertions/Links.java | 109 + .../java/h10/assertions/TestConstants.java | 26 + .../java/h10/assertions/TutorAssertions.java | 89 + .../graderPublic/java/h10/rubric/Builder.java | 16 + .../java/h10/rubric/Criteriable.java | 19 + .../java/h10/rubric/H10_RubricProvider.java | 238 + .../java/h10/rubric/H10_Tests.java | 155 + .../graderPublic/java/h10/rubric/Subtask.java | 312 + .../graderPublic/java/h10/rubric/Task.java | 101 + .../graderPublic/java/h10/util/ListItems.java | 92 + .../graderPublic/java/h10/util/MockList.java | 150 + .../graderPublic/resources/h10/H10_1_1.json | 37 + .../resources/h10/H10_1_CountSkipCards.json | 234 + .../graderPublic/resources/h10/H10_2_1.json | 76 + .../resources/h10/H10_2_2_Position.json | 42 + .../resources/h10/H10_2_3_Exception.json | 92 + .../resources/h10/H10_2_3_Start.json | 50 + .../resources/h10/H10_2_4_Case4.json | 30 + .../resources/h10/H10_2_4_References.json | 26 + .../graderPublic/resources/h10/H10_2_5.json | 36 + .../main/java/h10/BidirectionalIterator.java | 60 + H10/src/main/java/h10/CardGame.java | 147 + H10/src/main/java/h10/CardGamePlayer.java | 83 + H10/src/main/java/h10/DoublyLinkedList.java | 258 + H10/src/main/java/h10/ListItem.java | 63 + H10/src/main/java/h10/ListItemExamples.java | 59 + H10/src/main/java/h10/Main.java | 20 + H10/src/main/java/h10/MyList.java | 86 + H10/src/main/java/h10/PlayingCard.java | 39 + H10/src/test/java/h10/ExampleJUnitTest.java | 16 + H11/.editorconfig | 12 + H11/.gitignore | 86 + H11/README.md | 4 + H11/build.gradle.kts | 31 + H11/gradle/libs.versions.toml | 2 + H11/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes H11/gradle/wrapper/gradle-wrapper.properties | 6 + H11/gradlew | 249 + H11/gradlew.bat | 92 + H11/settings.gradle.kts | 10 + H11/src/graderPublic/java/h11/AlbumTest.java | 81 + H11/src/graderPublic/java/h11/ArtistTest.java | 75 + .../java/h11/H11_RubricProviderPublic.java | 351 + H11/src/graderPublic/java/h11/H11_Test.java | 154 + H11/src/graderPublic/java/h11/Invocation.java | 24 + .../graderPublic/java/h11/JsonConverter.java | 267 + .../graderPublic/java/h11/MockConverter.java | 597 + .../java/h11/MusicStreamingTest.java | 386 + .../java/h11/ReflectionUtils.java | 416 + H11/src/graderPublic/java/h11/SongTest.java | 37 + H11/src/graderPublic/java/h11/UserTest.java | 195 + .../h11/Album_getAverageDuration_empty.json | 30 + .../h11/Album_getAverageDuration_full.json | 517 + .../h11/Album_getSongsLongerThan.json | 533 + .../h11/Artist_getAllGenres_general.json | 370 + .../h11/Artist_getAllGenres_unique.json | 252 + .../resources/h11/Artist_getAllSongs.json | 1064 + .../MusicStreaming_adjustPrice_general.json | 615 + ...MusicStreaming_generateRandomPlaylist.json | 653 + ...Streaming_getGlobalPlayCounts_general.json | 245 + ...icStreaming_getMostPlayedArtist_empty.json | 262 + ...sicStreaming_getMostPlayedArtist_full.json | 3317 + .../h11/MusicStreaming_searchSongs.json | 1240 + .../resources/h11/Song_isLongerThan.json | 161 + .../h11/User_getPlayCounts_return.json | 329 + .../h11/User_getPlayedSongs_general.json | 189 + .../h11/User_getPlayedSongs_unique.json | 315 + H11/src/graderPublic/resources/packages.txt | 1 + H11/src/main/java/h11/Album.java | 39 + H11/src/main/java/h11/Artist.java | 37 + H11/src/main/java/h11/Genre.java | 24 + H11/src/main/java/h11/Main.java | 15 + H11/src/main/java/h11/MusicStreaming.java | 171 + H11/src/main/java/h11/PlayedSong.java | 12 + H11/src/main/java/h11/Song.java | 25 + H11/src/main/java/h11/User.java | 142 + H11/src/test/java/h11/ExampleJUnitTest.java | 16 + H12/.editorconfig | 12 + H12/.gitignore | 85 + H12/README.md | 4 + H12/build.gradle.kts | 31 + H12/gradle/libs.versions.toml | 2 + H12/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes H12/gradle/wrapper/gradle-wrapper.properties | 6 + H12/gradlew | 249 + H12/gradlew.bat | 92 + H12/settings.gradle.kts | 10 + .../java/h12/H12_1_1_TestsPublic.java | 305 + .../java/h12/H12_2_1_TestsPublic.java | 233 + .../java/h12/H12_3_2_TestsPublic.java | 188 + .../java/h12/H12_4_1_TestsPublic.java | 226 + .../java/h12/H12_RubricProviderPublic.java | 18 + H12/src/graderPublic/java/h12/H12_Tests.java | 138 + .../graderPublic/java/h12/JsonConverters.java | 95 + .../java/h12/TestInformation.java | 234 + .../java/h12/assertions/Links.java | 80 + .../java/h12/assertions/TestConstants.java | 25 + .../java/h12/mock/MockBitInputStream.java | 105 + .../java/h12/mock/MockBitOutputStream.java | 84 + .../h12/mock/MockHuffmanEncodingTable.java | 82 + .../graderPublic/java/h12/rubric/Builder.java | 18 + .../java/h12/rubric/Criteriable.java | 19 + .../java/h12/rubric/H12_RubricProvider.java | 192 + .../graderPublic/java/h12/rubric/Subtask.java | 324 + .../graderPublic/java/h12/rubric/Task.java | 106 + .../resources/h12/H12_1_1_testFetchEOF.json | 12 + .../h12/H12_1_1_testFetchNotEOF.json | 36 + .../resources/h12/H12_1_1_testRead.json | 115 + .../h12/H12_1_1_testReadBitBufferEnd.json | 45 + .../h12/H12_1_1_testReadBitBufferMiddle.json | 45 + .../h12/H12_1_1_testReadBitBufferStart.json | 45 + .../resources/h12/H12_1_1_testReadBitEOF.json | 13 + .../h12/H12_1_1_testReadBitNextByte.json | 72 + .../resources/h12/H12_1_1_testReadEnd.json | 13 + .../h12/H12_1_1_testReadPartial.json | 13 + .../h12/H12_1_Tests_testCompress.json | 349 + .../h12/H12_1_Tests_testGetBitCountMax.json | 560 + .../H12_1_Tests_testGetBitCountNotMax.json | 516 + .../h12/H12_3_2_Tests_testRemoveMin.json | 118 + .../resources/h12/H12_4_1_testCompress.json | 17458 ++++ .../h12/H12_4_1_testComputeTextSize.json | 79 + .../resources/h12/H12_4_1_testEncodeText.json | 15422 +++ .../resources/h12/H12_4_1_testGetText.json | 17 + H12/src/main/java/h12/Main.java | 16 + H12/src/main/java/h12/io/BitInputStream.java | 20 + H12/src/main/java/h12/io/BitOutStream.java | 23 + .../java/h12/io/BufferedBitInputStream.java | 112 + .../java/h12/io/BufferedBitOutputStream.java | 83 + .../main/java/h12/io/compress/Compressor.java | 22 + .../java/h12/io/compress/Decompressor.java | 22 + .../java/h12/io/compress/EncodingTable.java | 71 + .../io/compress/huffman/HuffmanCoding.java | 108 + .../huffman/HuffmanCodingCompressor.java | 191 + .../huffman/HuffmanCodingDecompressor.java | 141 + .../huffman/HuffmanEncodingTable.java | 223 + .../io/compress/huffman/HuffmanTreeNode.java | 77 + .../rle/BitRunningLengthCompressor.java | 87 + .../rle/BitRunningLengthDecompressor.java | 78 + H12/src/main/java/h12/lang/MyBit.java | 95 + H12/src/main/java/h12/lang/MyByte.java | 237 + H12/src/main/java/h12/lang/MyBytes.java | 112 + H12/src/main/java/h12/util/TreeNode.java | 173 + H12/src/test/java/h12/ExampleJUnitTest.java | 16 + .../graderPrivate/java/h02/FourWinsTest.java | 6 +- solution/H03/build.gradle.kts | 2 + solution/H03/gradle/libs.versions.toml | 2 +- .../java/h03/H03_RubricProvider.java | 2 +- solution/H04/build.gradle.kts | 2 + solution/H04/gradle/libs.versions.toml | 2 +- .../java/h04/H04_RubricProvider.java | 2 +- solution/H05/build.gradle.kts | 5 + solution/H05/gradle/libs.versions.toml | 2 +- .../java/h05/H05_RubricProvider.java | 2 +- .../.gradle/8.10.2/checksums/checksums.lock | Bin 0 -> 17 bytes .../8.10.2/checksums/md5-checksums.bin | Bin 0 -> 20947 bytes .../8.10.2/checksums/sha1-checksums.bin | Bin 0 -> 23789 bytes .../dm/LibrariesForLibs$BundleAccessors.class | Bin 0 -> 765 bytes .../dm/LibrariesForLibs$PluginAccessors.class | Bin 0 -> 967 bytes .../LibrariesForLibs$VersionAccessors.class | Bin 0 -> 601 bytes .../accessors/dm/LibrariesForLibs.class | Bin 0 -> 2597 bytes ...orLibsInPluginsBlock$BundleAccessors.class | Bin 0 -> 891 bytes ...orLibsInPluginsBlock$PluginAccessors.class | Bin 0 -> 1009 bytes ...rLibsInPluginsBlock$VersionAccessors.class | Bin 0 -> 643 bytes .../dm/LibrariesForLibsInPluginsBlock.class | Bin 0 -> 3963 bytes .../metadata.bin | 1 + .../gradle/accessors/dm/LibrariesForLibs.java | 89 + .../dm/LibrariesForLibsInPluginsBlock.java | 97 + .../dependencies-accessors/gc.properties | 0 .../executionHistory/executionHistory.bin | Bin 0 -> 118101 bytes .../executionHistory/executionHistory.lock | Bin 0 -> 17 bytes .../.gradle/8.10.2/fileChanges/last-build.bin | Bin 0 -> 1 bytes .../.gradle/8.10.2/fileHashes/fileHashes.bin | Bin 0 -> 22547 bytes .../.gradle/8.10.2/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .../8.10.2/fileHashes/resourceHashesCache.bin | Bin 0 -> 19857 bytes solution/H07/.gradle/8.10.2/gc.properties | 0 .../buildOutputCleanup.lock | Bin 0 -> 17 bytes .../buildOutputCleanup/cache.properties | 2 + .../buildOutputCleanup/outputFiles.bin | Bin 0 -> 19253 bytes solution/H07/.gradle/vcs-1/gc.properties | 0 solution/H07/.idea/.gitignore | 5 + solution/H07/.idea/.name | 1 + solution/H07/.idea/codeStyles/Project.xml | 7 + .../H07/.idea/codeStyles/codeStyleConfig.xml | 5 + solution/H07/.idea/compiler.xml | 6 + solution/H07/.idea/gradle.xml | 16 + solution/H07/.idea/misc.xml | 8 + solution/H07/.idea/sbt.xml | 7 + solution/H07/.idea/vcs.xml | 6 + .../h07/ArithmeticExpressionTest.class | Bin 0 -> 1024 bytes .../graderPrivate/h07/ClassReference.class | Bin 0 -> 10695 bytes ...nvertNumberToPeanoExpressionImplTest.class | Bin 0 -> 6548 bytes .../ConvertNumberToPeanoExpressionTest.class | Bin 0 -> 1079 bytes ...nvertPeanoToNumberExpressionImplTest.class | Bin 0 -> 6798 bytes .../ConvertPeanoToNumberExpressionTest.class | Bin 0 -> 1079 bytes .../java/graderPrivate/h07/H07Test$1.class | Bin 0 -> 1637 bytes .../java/graderPrivate/h07/H07Test.class | Bin 0 -> 5067 bytes .../h07/H07_RubricProvider.class | Bin 0 -> 15379 bytes .../graderPrivate/h07/MethodReference.class | Bin 0 -> 23733 bytes .../graderPrivate/h07/NumberConverter.class | Bin 0 -> 2827 bytes .../h07/NumberExpressionFactoryTest.class | Bin 0 -> 15193 bytes .../h07/NumberExpressionTest.class | Bin 0 -> 999 bytes .../h07/PeanoAddExpressionTest.class | Bin 0 -> 6756 bytes .../h07/PeanoArithmeticExpressionTest.class | Bin 0 -> 1051 bytes .../h07/PeanoMultiplyExpressionTest.class | Bin 0 -> 6793 bytes .../PeanoNumberExpressionFactoryTest.class | Bin 0 -> 11319 bytes .../h07/PeanoNumberExpressionTest.class | Bin 0 -> 1031 bytes .../java/graderPrivate/h07/Tests$1$1.class | Bin 0 -> 2273 bytes .../java/graderPrivate/h07/Tests$1.class | Bin 0 -> 1428 bytes .../java/graderPrivate/h07/Tests.class | Bin 0 -> 1770 bytes .../build/classes/java/main/h07/Main.class | Bin 0 -> 2188 bytes .../main/h07/NumberExpressionFactory.class | Bin 0 -> 302 bytes .../java/main/h07/peano/NaturalNumber.class | Bin 0 -> 424 bytes .../peano/PeanoNumberExpressionFactory.class | Bin 0 -> 329 bytes .../java/main/h07/peano/Successor.class | Bin 0 -> 1054 bytes .../classes/java/main/h07/peano/Zero.class | Bin 0 -> 462 bytes .../java/test/h07/ExampleJUnitTest.class | Bin 0 -> 504 bytes .../jagr/graderPrivate/grader-info.json | 1 + .../h07_ab12cdef_sol_last_sol_first.html | 1 + .../h07_ab12cdef_sol_last_sol_first.json | 1 + .../resources/jagr/main/submission-info.json | 1 + .../previous-compilation-data.bin | Bin 0 -> 53552 bytes .../compileJava/previous-compilation-data.bin | Bin 0 -> 3675 bytes .../previous-compilation-data.bin | Bin 0 -> 4086 bytes solution/H07/jagr.conf | 70 + solution/H07/src/main | 1 - solution/H07/src/test | 1 - solution/H08/.editorconfig | 12 + solution/{H07 => H08}/.gitignore | 1 - solution/H08/README.md | 4 + solution/H08/build.gradle.kts | 48 + solution/H08/gradle/libs.versions.toml | 3 + .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 6 + solution/{H07 => H08}/gradlew | 0 solution/{H07 => H08}/gradlew.bat | 0 solution/H08/settings.gradle.kts | 15 + .../java/h08/H08_1_TestsPrivate.java | 170 + .../java/h08/H08_2_1_TestsPrivate.java | 164 + .../java/h08/H08_2_2_TestsPrivate.java | 119 + .../java/h08/H08_3_TestsPrivate.java | 62 + .../java/h08/H08_4_1_TestsPrivate.java | 117 + .../java/h08/H08_4_2_TestsPrivate.java | 137 + .../java/h08/H08_4_3_TestsPrivate.java | 120 + .../java/h08/H08_4_4_TestsPrivate.java | 113 + .../java/h08/H08_5_1_TestsPrivate.java | 238 + .../java/h08/H08_5_2_TestsPrivate.java | 189 + .../java/h08/H08_5_3_TestsPrivate.java | 165 + .../java/h08/H08_5_4_TestsPrivate.java | 141 + .../java/h08/H08_5_5_TestsPrivate.java | 201 + .../java/h08/H08_RubricProvider.java | 226 + .../src/graderPrivate/java/h08/H08_Tests.java | 113 + .../java/h08/JsonConverters.java | 166 + .../graderPrivate/java/h08/TestConstants.java | 38 + .../graderPrivate/java/h08/TutorUtils.java | 91 + .../java/h08/assertions/ClassReference.java | 337 + .../java/h08/assertions/Links.java | 136 + .../java/h08/assertions/Matchers.java | 65 + .../java/h08/assertions/Mocks.java | 70 + .../java/h08/mocks/FakeAirport.java | 170 + .../java/h08/mocks/FakeBookingManagement.java | 82 + .../java/h08/rubric/Builder.java | 18 + .../java/h08/rubric/Criteriable.java | 19 + .../java/h08/rubric/Rubrics.java | 103 + .../java/h08/rubric/TaskRubricProvider.java | 62 + .../BasicSubtestInformationBuilder.java | 36 + .../context/InputTestInformationBuilder.java | 10 + .../InputTestInformationBuilderImpl.java | 15 + .../context/OutputTestInformationBuilder.java | 12 + .../OutputTestInformationBuilderImpl.java | 24 + .../rubric/context/SubtestInformation.java | 38 + .../h08/rubric/context/TestInformation.java | 234 + .../java/h08/rubric/task/AtomicTask.java | 150 + .../java/h08/rubric/task/AtomicTaskImpl.java | 182 + .../java/h08/rubric/task/CompositeTask.java | 64 + .../h08/rubric/task/CompositeTaskImpl.java | 80 + .../java/h08/rubric/task/Subtask.java | 18 + .../java/h08/rubric/task/SubtaskImpl.java | 24 + .../java/h08/rubric/task/Task.java | 13 + .../java/h08/util/TriFunction.java | 42 + .../h08/H08_1_generatePassengerID.json | 18 + .../h08/H08_2_1_testFlightConstructor.json | 30 + ...2_1_testValidateFlightNumberException.json | 23 + .../resources/h08/H08_2_2_testBookSeat.json | 56 + .../resources/h08/H08_4_1_testAddFlight.json | 248 + .../h08/H08_4_1_testAddFlightException.json | 92 + .../h08/H08_4_2_testRemoveFlight.json | 476 + .../H08_4_2_testRemoveFlightException.json | 80 + .../resources/h08/H08_4_3_testGetFlight.json | 416 + .../h08/H08_4_3_testGetFlightException.json | 142 + .../h08/H08_4_4_testCancelBooking.json | 11 + .../H08_4_4_testCancelBookingException.json | 12 + .../resources/h08/H08_5_1_testGetFlight.json | 392 + .../h08/H08_5_1_testGetFlightNull.json | 133 + .../h08/H08_5_1_testSearchAirport.json | 177 + .../H08_5_1_testSearchAirportException.json | 136 + .../h08/H08_5_1_testSearchFlight.json | 547 + .../h08/H08_5_2_testManageFlight.json | 274 + ..._5_2_validateAndCheckBookingDuplicate.json | 56 + ...08_5_2_validateAndCheckBookingInvalid.json | 326 + .../resources/h08/H08_5_3_testGetBooking.json | 80 + .../h08/H08_5_3_testGetBookingException.json | 30 + .../h08/H08_5_3_testSearchBooking.json | 80 + .../H08_5_3_testSearchBookingException.json | 30 + .../h08/H08_5_4_testCancelBooking.json | 83 + ...5_4_testCancelBookingAlreadyCancelled.json | 32 + .../H08_5_4_testCancelBookingNotFound.json | 30 + .../h08/H08_5_5_testCreateBooking.json | 61 + .../H08_5_5_testCreateBookingDuplicate.json | 57 + .../h08/H08_5_5_testCreateBookingInvalid.json | 57 + .../h08/H08_5_5_testCreateBookingNoSeats.json | 57 + .../H08_5_5_testCreateBookingValidation.json | 26 + solution/H08/src/main | 1 + solution/H08/src/test | 1 + solution/H08/version | 1 + solution/H09/.editorconfig | 12 + solution/H09/.gitignore | 86 + solution/H09/README.md | 4 + solution/{H07 => H09}/build.gradle.kts | 6 +- solution/H09/gradle/libs.versions.toml | 3 + .../H09/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + solution/H09/gradlew | 249 + solution/H09/gradlew.bat | 92 + solution/{H07 => H09}/settings.gradle.kts | 2 +- .../java/h09/H09_RubricProvider.java | 73 + .../java/h09/TemplateAnnotationProcessor.java | 154 + solution/H09/src/main | 1 + solution/H09/src/test | 1 + solution/H09/version | 1 + solution/H10/.editorconfig | 12 + solution/H10/.gitignore | 86 + solution/H10/README.md | 4 + solution/H10/build.gradle.kts | 39 + solution/H10/gradle/libs.versions.toml | 3 + .../H10/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 62076 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + solution/H10/gradlew | 245 + solution/H10/gradlew.bat | 92 + solution/H10/settings.gradle.kts | 10 + .../java/h10/H10_1_1_TestsPrivate.java | 24 + .../java/h10/H10_1_2_TestsPrivate.java | 67 + .../java/h10/H10_1_3_TestsPrivate.java | 67 + .../java/h10/H10_1_4_TestsPrivate.java | 40 + .../java/h10/H10_2_1_TestsPrivate.java | 36 + .../java/h10/H10_2_2_TestsPrivate.java | 86 + .../java/h10/H10_2_3_TestsPrivate.java | 144 + .../java/h10/H10_2_4_TestsPrivate.java | 104 + .../java/h10/H10_2_5_TestsPrivate.java | 25 + .../java/h10/H10_3_1_TestsPrivate.java | 24 + .../java/h10/H10_3_2_TestsPrivate.java | 167 + .../java/h10/H10_3_3_TestsPrivate.java | 220 + .../java/h10/H10_RubricProviderPrivate.java | 18 + .../java/h10/TutorAssertionsPrivate.java | 162 + .../resources/h10/H10_2_2_Exception.json | 120 + .../resources/h10/H10_2_2_Path.json | 162 + .../resources/h10/H10_2_3_End.json | 50 + .../resources/h10/H10_2_3_Middle.json | 61 + .../resources/h10/H10_2_3_Null.json | 42 + .../resources/h10/H10_2_3_Size.json | 38 + .../resources/h10/H10_2_4_Case2.json | 26 + .../resources/h10/H10_2_4_Case3.json | 26 + .../resources/h10/H10_2_4_Size.json | 40 + .../resources/h10/H10_3_3_Loser.json | 256 + .../src/graderPublic/java/h10/CardGames.java | 49 + .../java/h10/DoublyLinkedLists.java | 35 + .../java/h10/H10_1_1_TestsPublic.java | 88 + .../java/h10/H10_1_4_TestsPublic.java | 48 + .../java/h10/H10_1_CountSkipCards_Tests.java | 90 + .../java/h10/H10_2_1_TestsPublic.java | 65 + .../java/h10/H10_2_2_TestsPublic.java | 66 + .../java/h10/H10_2_3_TestsPublic.java | 126 + .../java/h10/H10_2_4_TestsPublic.java | 130 + .../java/h10/H10_2_5_TestsPublic.java | 66 + .../java/h10/H10_3_1_TestsPublic.java | 156 + .../java/h10/H10_3_3_TestsPublic.java | 206 + .../java/h10/H10_RubricProviderPublic.java | 18 + .../graderPublic/java/h10/JsonConverters.java | 107 + .../java/h10/assertions/Links.java | 109 + .../java/h10/assertions/TestConstants.java | 26 + .../java/h10/assertions/TutorAssertions.java | 89 + .../graderPublic/java/h10/rubric/Builder.java | 16 + .../java/h10/rubric/Criteriable.java | 19 + .../java/h10/rubric/H10_RubricProvider.java | 238 + .../java/h10/rubric/H10_Tests.java | 155 + .../graderPublic/java/h10/rubric/Subtask.java | 312 + .../graderPublic/java/h10/rubric/Task.java | 101 + .../graderPublic/java/h10/util/ListItems.java | 92 + .../graderPublic/java/h10/util/MockList.java | 150 + .../graderPublic/resources/h10/H10_1_1.json | 37 + .../resources/h10/H10_1_CountSkipCards.json | 234 + .../graderPublic/resources/h10/H10_2_1.json | 76 + .../resources/h10/H10_2_2_Position.json | 42 + .../resources/h10/H10_2_3_Exception.json | 92 + .../resources/h10/H10_2_3_Start.json | 50 + .../resources/h10/H10_2_4_Case4.json | 30 + .../resources/h10/H10_2_4_References.json | 26 + .../graderPublic/resources/h10/H10_2_5.json | 36 + solution/H10/src/main | 1 + solution/H10/src/test | 1 + solution/H10/version | 1 + solution/H11/.editorconfig | 12 + solution/H11/.gitignore | 86 + solution/H11/README.md | 4 + solution/H11/build.gradle.kts | 39 + solution/H11/gradle/libs.versions.toml | 3 + .../H11/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 62076 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + solution/H11/gradlew | 245 + solution/H11/gradlew.bat | 92 + solution/H11/settings.gradle.kts | 10 + .../java/h11/H11_RubricProvider.java | 373 + solution/H11/src/main | 1 + solution/H11/src/test | 1 + solution/H11/version | 1 + solution/H12/.editorconfig | 12 + solution/H12/.gitignore | 86 + solution/H12/README.md | 4 + solution/H12/build.gradle.kts | 39 + .../{H07 => H12}/gradle/libs.versions.toml | 0 .../H12/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 62076 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + solution/H12/gradlew | 245 + solution/H12/gradlew.bat | 92 + solution/H12/settings.gradle.kts | 10 + .../java/h12/H12_1_2_TestsPrivate.java | 434 + .../java/h12/H12_2_2_TestsPrivate.java | 241 + .../java/h12/H12_3_1_TestsPrivate.java | 116 + .../java/h12/H12_3_2_TestsPrivate.java | 57 + .../java/h12/H12_4_2_TestsPrivate.java | 268 + .../java/h12/H12_RubricProviderPrivate.java | 18 + .../h12/H12_1_2_testFlushBufferUpdateNo.json | 9 + .../h12/H12_1_2_testFlushBufferUpdateYes.json | 50 + .../h12/H12_1_2_testFlushBufferWrite.json | 18 + .../resources/h12/H12_1_2_testWrite.json | 102 + .../resources/h12/H12_1_2_testWriteBit.json | 66 + .../h12/H12_1_2_testWriteBitFlushNo.json | 26 + .../h12/H12_1_2_testWriteBitFlushYes.json | 19 + ...1_2_testWriteIllegalArgumentException.json | 26 + .../resources/h12/H12_2_2_testDecompress.json | 876 + .../h12/H12_2_2_testDecompressBitCount.json | 68 + .../resources/h12/H12_2_2_testWriteBit.json | 82 + .../h12/H12_3_1_testBuildFrequencyTable.json | 49 + .../h12/H12_4_2_testDecodeCharacter.json | 256 + .../resources/h12/H12_4_2_testDecodeText.json | 43479 ++++++++ .../resources/h12/H12_4_2_testDecompress.json | 86885 ++++++++++++++++ .../resources/h12/H12_4_2_testSkipBits.json | 32997 ++++++ .../java/h12/H12_1_1_TestsPublic.java | 305 + .../java/h12/H12_2_1_TestsPublic.java | 233 + .../java/h12/H12_3_2_TestsPublic.java | 188 + .../java/h12/H12_4_1_TestsPublic.java | 238 + .../java/h12/H12_RubricProviderPublic.java | 18 + .../src/graderPublic/java/h12/H12_Tests.java | 138 + .../graderPublic/java/h12/JsonConverters.java | 95 + .../java/h12/TestInformation.java | 234 + .../java/h12/assertions/Links.java | 80 + .../java/h12/assertions/TestConstants.java | 25 + .../java/h12/mock/MockBitInputStream.java | 105 + .../java/h12/mock/MockBitOutputStream.java | 94 + .../h12/mock/MockHuffmanEncodingTable.java | 82 + .../graderPublic/java/h12/rubric/Builder.java | 18 + .../java/h12/rubric/Criteriable.java | 19 + .../java/h12/rubric/H12_RubricProvider.java | 192 + .../graderPublic/java/h12/rubric/Subtask.java | 324 + .../graderPublic/java/h12/rubric/Task.java | 106 + .../resources/h12/H12_1_1_testFetchEOF.json | 12 + .../h12/H12_1_1_testFetchNotEOF.json | 36 + .../resources/h12/H12_1_1_testRead.json | 115 + .../h12/H12_1_1_testReadBitBufferEnd.json | 45 + .../h12/H12_1_1_testReadBitBufferMiddle.json | 45 + .../h12/H12_1_1_testReadBitBufferStart.json | 45 + .../resources/h12/H12_1_1_testReadBitEOF.json | 13 + .../h12/H12_1_1_testReadBitNextByte.json | 72 + .../resources/h12/H12_1_1_testReadEnd.json | 13 + .../h12/H12_1_1_testReadPartial.json | 13 + .../h12/H12_1_Tests_testCompress.json | 349 + .../h12/H12_1_Tests_testGetBitCountMax.json | 560 + .../H12_1_Tests_testGetBitCountNotMax.json | 516 + .../h12/H12_3_2_Tests_testRemoveMin.json | 118 + .../resources/h12/H12_4_1_testCompress.json | 17458 ++++ .../h12/H12_4_1_testComputeTextSize.json | 79 + .../resources/h12/H12_4_1_testEncodeText.json | 15422 +++ .../resources/h12/H12_4_1_testGetText.json | 17 + solution/H12/src/main | 1 + solution/H12/src/test | 1 + solution/H12/version | 1 + 619 files changed, 283313 insertions(+), 311 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 H01/src/main/java/h01/FuckBot.java create mode 100644 H03/src/main/java/h03/RobotsChallenge.java create mode 100644 H03/src/main/java/h03/robots/DoublePowerRobot.java create mode 100644 H03/src/main/java/h03/robots/HackingRobot.java create mode 100644 H03/src/main/java/h03/robots/MovementType.java create mode 100644 H03/src/main/java/h03/robots/VersatileRobot.java create mode 100644 H04/src/main/java/h04/movement/DiagonalMover.java create mode 100644 H04/src/main/java/h04/movement/MoveStrategy.java create mode 100644 H04/src/main/java/h04/movement/OrthogonalMover.java create mode 100644 H04/src/main/java/h04/movement/TeleportingMoveStrategy.java create mode 100644 H04/src/main/java/h04/movement/WalkingMoveStrategy.java create mode 100644 H05/src/main/java/h05/CargoPlane.java create mode 100644 H05/src/main/java/h05/CarriesCargo.java create mode 100644 H05/src/main/java/h05/CarriesPassengers.java create mode 100644 H05/src/main/java/h05/CombinedPlane.java create mode 100644 H05/src/main/java/h05/Flying.java create mode 100644 H05/src/main/java/h05/FuelType.java create mode 100644 H05/src/main/java/h05/PassengerPlane.java create mode 100644 H05/src/main/java/h05/Plane.java create mode 100644 H05/src/main/java/h05/Refuelling.java create mode 100644 H05/src/main/java/h05/Runway.java create mode 100644 H05/src/main/java/h05/Tank.java create mode 100644 H05/src/main/java/h05/TankerPlane.java create mode 100644 H05/src/main/java/h05/WeatherBalloon.java delete mode 100644 H07/src/main/java/h07/Main.java delete mode 100644 H07/src/main/java/h07/NumberExpressionFactory.java delete mode 100644 H07/src/main/java/h07/peano/NaturalNumber.java delete mode 100644 H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java delete mode 100644 H07/src/main/java/h07/peano/Successor.java delete mode 100644 H07/src/main/java/h07/peano/Zero.java rename {H07 => H08}/.editorconfig (100%) rename {H07 => H08}/.gitignore (100%) rename {H07 => H08}/README.md (85%) rename {H07 => H08}/build.gradle.kts (91%) rename {H07 => H08}/gradle/libs.versions.toml (100%) rename {H07 => H08}/gradle/wrapper/gradle-wrapper.jar (100%) rename {H07 => H08}/gradle/wrapper/gradle-wrapper.properties (100%) rename {H07 => H08}/gradlew (100%) rename {H07 => H08}/gradlew.bat (100%) rename {H07 => H08}/settings.gradle.kts (89%) create mode 100644 H08/src/main/java/h08/Airport.java create mode 100644 H08/src/main/java/h08/Booking.java create mode 100644 H08/src/main/java/h08/BookingManagement.java create mode 100644 H08/src/main/java/h08/Flight.java create mode 100644 H08/src/main/java/h08/FlightManagement.java create mode 100644 H08/src/main/java/h08/Main.java create mode 100644 H08/src/main/java/h08/Passenger.java rename {H07/src/test/java/h07 => H08/src/test/java/h08}/ExampleJUnitTest.java (94%) rename {solution/H07 => H09}/.editorconfig (100%) create mode 100644 H09/.gitignore rename {solution/H07 => H09}/README.md (82%) create mode 100644 H09/build.gradle.kts create mode 100644 H09/gradle/libs.versions.toml create mode 100644 H09/gradle/wrapper/gradle-wrapper.jar create mode 100644 H09/gradle/wrapper/gradle-wrapper.properties create mode 100755 H09/gradlew create mode 100644 H09/gradlew.bat create mode 100644 H09/settings.gradle.kts create mode 100644 H09/src/graderPublic/java/h09/EnclosureTestPublic.java create mode 100644 H09/src/graderPublic/java/h09/H09_RubricProviderPublic.java create mode 100644 H09/src/graderPublic/java/h09/H09_TestUtils.java create mode 100644 H09/src/graderPublic/java/h09/ReflectionUtils.java create mode 100644 H09/src/graderPublic/java/h09/StackOfObjectsTestPublic.java create mode 100644 H09/src/graderPublic/java/h09/WaterEnclosureTestPublic.java create mode 100644 H09/src/main/java/h09/Enclosure.java create mode 100644 H09/src/main/java/h09/GroundEnclosure.java create mode 100644 H09/src/main/java/h09/Main.java create mode 100644 H09/src/main/java/h09/StackOfObjects.java create mode 100644 H09/src/main/java/h09/WaterEnclosure.java create mode 100644 H09/src/main/java/h09/abilities/Flies.java create mode 100644 H09/src/main/java/h09/abilities/Swims.java create mode 100644 H09/src/main/java/h09/abilities/Walks.java create mode 100644 H09/src/main/java/h09/animals/Animal.java create mode 100644 H09/src/main/java/h09/animals/ClownFish.java create mode 100644 H09/src/main/java/h09/animals/Fish.java create mode 100644 H09/src/main/java/h09/animals/FlyingFish.java create mode 100644 H09/src/main/java/h09/animals/JugglingLion.java create mode 100644 H09/src/main/java/h09/animals/KingPenguin.java create mode 100644 H09/src/main/java/h09/animals/Lion.java create mode 100644 H09/src/main/java/h09/animals/Penguin.java create mode 100644 H09/src/main/java/h09/animals/Turtle.java create mode 100644 H09/src/test/java/h09/EnclosureTest.java create mode 100644 H09/src/test/java/h09/ExampleJUnitTest.java create mode 100644 H09/src/test/java/h09/ExampleZooTest.java rename {solution/H07 => H09}/version (100%) create mode 100644 H10/.editorconfig create mode 100644 H10/.gitignore create mode 100644 H10/README.md create mode 100644 H10/build.gradle.kts create mode 100644 H10/gradle/libs.versions.toml create mode 100644 H10/gradle/wrapper/gradle-wrapper.jar rename {solution/H07 => H10}/gradle/wrapper/gradle-wrapper.properties (100%) create mode 100755 H10/gradlew create mode 100644 H10/gradlew.bat create mode 100644 H10/settings.gradle.kts create mode 100644 H10/src/graderPublic/java/h10/CardGames.java create mode 100644 H10/src/graderPublic/java/h10/DoublyLinkedLists.java create mode 100644 H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java create mode 100644 H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java create mode 100644 H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java create mode 100644 H10/src/graderPublic/java/h10/JsonConverters.java create mode 100644 H10/src/graderPublic/java/h10/assertions/Links.java create mode 100644 H10/src/graderPublic/java/h10/assertions/TestConstants.java create mode 100644 H10/src/graderPublic/java/h10/assertions/TutorAssertions.java create mode 100644 H10/src/graderPublic/java/h10/rubric/Builder.java create mode 100644 H10/src/graderPublic/java/h10/rubric/Criteriable.java create mode 100644 H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java create mode 100644 H10/src/graderPublic/java/h10/rubric/H10_Tests.java create mode 100644 H10/src/graderPublic/java/h10/rubric/Subtask.java create mode 100644 H10/src/graderPublic/java/h10/rubric/Task.java create mode 100644 H10/src/graderPublic/java/h10/util/ListItems.java create mode 100644 H10/src/graderPublic/java/h10/util/MockList.java create mode 100644 H10/src/graderPublic/resources/h10/H10_1_1.json create mode 100644 H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_1.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_2_Position.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_3_Exception.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_3_Start.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_4_Case4.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_4_References.json create mode 100644 H10/src/graderPublic/resources/h10/H10_2_5.json create mode 100644 H10/src/main/java/h10/BidirectionalIterator.java create mode 100644 H10/src/main/java/h10/CardGame.java create mode 100644 H10/src/main/java/h10/CardGamePlayer.java create mode 100644 H10/src/main/java/h10/DoublyLinkedList.java create mode 100644 H10/src/main/java/h10/ListItem.java create mode 100644 H10/src/main/java/h10/ListItemExamples.java create mode 100644 H10/src/main/java/h10/Main.java create mode 100644 H10/src/main/java/h10/MyList.java create mode 100644 H10/src/main/java/h10/PlayingCard.java create mode 100644 H10/src/test/java/h10/ExampleJUnitTest.java create mode 100644 H11/.editorconfig create mode 100644 H11/.gitignore create mode 100644 H11/README.md create mode 100644 H11/build.gradle.kts create mode 100644 H11/gradle/libs.versions.toml create mode 100644 H11/gradle/wrapper/gradle-wrapper.jar create mode 100644 H11/gradle/wrapper/gradle-wrapper.properties create mode 100755 H11/gradlew create mode 100644 H11/gradlew.bat create mode 100644 H11/settings.gradle.kts create mode 100644 H11/src/graderPublic/java/h11/AlbumTest.java create mode 100644 H11/src/graderPublic/java/h11/ArtistTest.java create mode 100644 H11/src/graderPublic/java/h11/H11_RubricProviderPublic.java create mode 100644 H11/src/graderPublic/java/h11/H11_Test.java create mode 100644 H11/src/graderPublic/java/h11/Invocation.java create mode 100644 H11/src/graderPublic/java/h11/JsonConverter.java create mode 100644 H11/src/graderPublic/java/h11/MockConverter.java create mode 100644 H11/src/graderPublic/java/h11/MusicStreamingTest.java create mode 100644 H11/src/graderPublic/java/h11/ReflectionUtils.java create mode 100644 H11/src/graderPublic/java/h11/SongTest.java create mode 100644 H11/src/graderPublic/java/h11/UserTest.java create mode 100644 H11/src/graderPublic/resources/h11/Album_getAverageDuration_empty.json create mode 100644 H11/src/graderPublic/resources/h11/Album_getAverageDuration_full.json create mode 100644 H11/src/graderPublic/resources/h11/Album_getSongsLongerThan.json create mode 100644 H11/src/graderPublic/resources/h11/Artist_getAllGenres_general.json create mode 100644 H11/src/graderPublic/resources/h11/Artist_getAllGenres_unique.json create mode 100644 H11/src/graderPublic/resources/h11/Artist_getAllSongs.json create mode 100644 H11/src/graderPublic/resources/h11/MusicStreaming_adjustPrice_general.json create mode 100644 H11/src/graderPublic/resources/h11/MusicStreaming_generateRandomPlaylist.json create mode 100644 H11/src/graderPublic/resources/h11/MusicStreaming_getGlobalPlayCounts_general.json create mode 100644 H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_empty.json create mode 100644 H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_full.json create mode 100644 H11/src/graderPublic/resources/h11/MusicStreaming_searchSongs.json create mode 100644 H11/src/graderPublic/resources/h11/Song_isLongerThan.json create mode 100644 H11/src/graderPublic/resources/h11/User_getPlayCounts_return.json create mode 100644 H11/src/graderPublic/resources/h11/User_getPlayedSongs_general.json create mode 100644 H11/src/graderPublic/resources/h11/User_getPlayedSongs_unique.json create mode 100644 H11/src/graderPublic/resources/packages.txt create mode 100644 H11/src/main/java/h11/Album.java create mode 100644 H11/src/main/java/h11/Artist.java create mode 100644 H11/src/main/java/h11/Genre.java create mode 100644 H11/src/main/java/h11/Main.java create mode 100644 H11/src/main/java/h11/MusicStreaming.java create mode 100644 H11/src/main/java/h11/PlayedSong.java create mode 100644 H11/src/main/java/h11/Song.java create mode 100644 H11/src/main/java/h11/User.java create mode 100644 H11/src/test/java/h11/ExampleJUnitTest.java create mode 100644 H12/.editorconfig create mode 100644 H12/.gitignore create mode 100644 H12/README.md create mode 100644 H12/build.gradle.kts create mode 100644 H12/gradle/libs.versions.toml create mode 100644 H12/gradle/wrapper/gradle-wrapper.jar create mode 100644 H12/gradle/wrapper/gradle-wrapper.properties create mode 100755 H12/gradlew create mode 100644 H12/gradlew.bat create mode 100644 H12/settings.gradle.kts create mode 100644 H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java create mode 100644 H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java create mode 100644 H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java create mode 100644 H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java create mode 100644 H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java create mode 100644 H12/src/graderPublic/java/h12/H12_Tests.java create mode 100644 H12/src/graderPublic/java/h12/JsonConverters.java create mode 100644 H12/src/graderPublic/java/h12/TestInformation.java create mode 100644 H12/src/graderPublic/java/h12/assertions/Links.java create mode 100644 H12/src/graderPublic/java/h12/assertions/TestConstants.java create mode 100644 H12/src/graderPublic/java/h12/mock/MockBitInputStream.java create mode 100644 H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java create mode 100644 H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java create mode 100644 H12/src/graderPublic/java/h12/rubric/Builder.java create mode 100644 H12/src/graderPublic/java/h12/rubric/Criteriable.java create mode 100644 H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java create mode 100644 H12/src/graderPublic/java/h12/rubric/Subtask.java create mode 100644 H12/src/graderPublic/java/h12/rubric/Task.java create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testRead.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json create mode 100644 H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json create mode 100644 H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json create mode 100644 H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json create mode 100644 H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json create mode 100644 H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json create mode 100644 H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json create mode 100644 H12/src/main/java/h12/Main.java create mode 100644 H12/src/main/java/h12/io/BitInputStream.java create mode 100644 H12/src/main/java/h12/io/BitOutStream.java create mode 100644 H12/src/main/java/h12/io/BufferedBitInputStream.java create mode 100644 H12/src/main/java/h12/io/BufferedBitOutputStream.java create mode 100644 H12/src/main/java/h12/io/compress/Compressor.java create mode 100644 H12/src/main/java/h12/io/compress/Decompressor.java create mode 100644 H12/src/main/java/h12/io/compress/EncodingTable.java create mode 100644 H12/src/main/java/h12/io/compress/huffman/HuffmanCoding.java create mode 100644 H12/src/main/java/h12/io/compress/huffman/HuffmanCodingCompressor.java create mode 100644 H12/src/main/java/h12/io/compress/huffman/HuffmanCodingDecompressor.java create mode 100644 H12/src/main/java/h12/io/compress/huffman/HuffmanEncodingTable.java create mode 100644 H12/src/main/java/h12/io/compress/huffman/HuffmanTreeNode.java create mode 100644 H12/src/main/java/h12/io/compress/rle/BitRunningLengthCompressor.java create mode 100644 H12/src/main/java/h12/io/compress/rle/BitRunningLengthDecompressor.java create mode 100644 H12/src/main/java/h12/lang/MyBit.java create mode 100644 H12/src/main/java/h12/lang/MyByte.java create mode 100644 H12/src/main/java/h12/lang/MyBytes.java create mode 100644 H12/src/main/java/h12/util/TreeNode.java create mode 100644 H12/src/test/java/h12/ExampleJUnitTest.java create mode 100644 solution/H07/.gradle/8.10.2/checksums/checksums.lock create mode 100644 solution/H07/.gradle/8.10.2/checksums/md5-checksums.bin create mode 100644 solution/H07/.gradle/8.10.2/checksums/sha1-checksums.bin create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$BundleAccessors.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$PluginAccessors.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$VersionAccessors.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock$BundleAccessors.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock$PluginAccessors.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock$VersionAccessors.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.class create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/metadata.bin create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibs.java create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.java create mode 100644 solution/H07/.gradle/8.10.2/dependencies-accessors/gc.properties create mode 100644 solution/H07/.gradle/8.10.2/executionHistory/executionHistory.bin create mode 100644 solution/H07/.gradle/8.10.2/executionHistory/executionHistory.lock create mode 100644 solution/H07/.gradle/8.10.2/fileChanges/last-build.bin create mode 100644 solution/H07/.gradle/8.10.2/fileHashes/fileHashes.bin create mode 100644 solution/H07/.gradle/8.10.2/fileHashes/fileHashes.lock create mode 100644 solution/H07/.gradle/8.10.2/fileHashes/resourceHashesCache.bin create mode 100644 solution/H07/.gradle/8.10.2/gc.properties create mode 100644 solution/H07/.gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 solution/H07/.gradle/buildOutputCleanup/cache.properties create mode 100644 solution/H07/.gradle/buildOutputCleanup/outputFiles.bin create mode 100644 solution/H07/.gradle/vcs-1/gc.properties create mode 100644 solution/H07/.idea/.gitignore create mode 100644 solution/H07/.idea/.name create mode 100644 solution/H07/.idea/codeStyles/Project.xml create mode 100644 solution/H07/.idea/codeStyles/codeStyleConfig.xml create mode 100644 solution/H07/.idea/compiler.xml create mode 100644 solution/H07/.idea/gradle.xml create mode 100644 solution/H07/.idea/misc.xml create mode 100644 solution/H07/.idea/sbt.xml create mode 100644 solution/H07/.idea/vcs.xml create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/ArithmeticExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/ClassReference.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/ConvertNumberToPeanoExpressionImplTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/ConvertNumberToPeanoExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/ConvertPeanoToNumberExpressionImplTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/ConvertPeanoToNumberExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/H07Test$1.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/H07Test.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/H07_RubricProvider.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/MethodReference.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/NumberConverter.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/NumberExpressionFactoryTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/NumberExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/PeanoAddExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/PeanoArithmeticExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/PeanoMultiplyExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/PeanoNumberExpressionFactoryTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/PeanoNumberExpressionTest.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/Tests$1$1.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/Tests$1.class create mode 100644 solution/H07/build/classes/java/graderPrivate/h07/Tests.class create mode 100644 solution/H07/build/classes/java/main/h07/Main.class create mode 100644 solution/H07/build/classes/java/main/h07/NumberExpressionFactory.class create mode 100644 solution/H07/build/classes/java/main/h07/peano/NaturalNumber.class create mode 100644 solution/H07/build/classes/java/main/h07/peano/PeanoNumberExpressionFactory.class create mode 100644 solution/H07/build/classes/java/main/h07/peano/Successor.class create mode 100644 solution/H07/build/classes/java/main/h07/peano/Zero.class create mode 100644 solution/H07/build/classes/java/test/h07/ExampleJUnitTest.class create mode 100644 solution/H07/build/resources/jagr/graderPrivate/grader-info.json create mode 100644 solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.html create mode 100644 solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.json create mode 100644 solution/H07/build/resources/jagr/main/submission-info.json create mode 100644 solution/H07/build/tmp/compileGraderPrivateJava/previous-compilation-data.bin create mode 100644 solution/H07/build/tmp/compileJava/previous-compilation-data.bin create mode 100644 solution/H07/build/tmp/compileTestJava/previous-compilation-data.bin create mode 100644 solution/H07/jagr.conf delete mode 120000 solution/H07/src/main delete mode 120000 solution/H07/src/test create mode 100644 solution/H08/.editorconfig rename solution/{H07 => H08}/.gitignore (99%) create mode 100644 solution/H08/README.md create mode 100644 solution/H08/build.gradle.kts create mode 100644 solution/H08/gradle/libs.versions.toml rename solution/{H07 => H08}/gradle/wrapper/gradle-wrapper.jar (100%) create mode 100644 solution/H08/gradle/wrapper/gradle-wrapper.properties rename solution/{H07 => H08}/gradlew (100%) rename solution/{H07 => H08}/gradlew.bat (100%) create mode 100644 solution/H08/settings.gradle.kts create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_1_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_2_1_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_2_2_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_3_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_4_1_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_4_2_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_4_3_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_4_4_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_5_1_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_5_2_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_5_3_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_5_4_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_5_5_TestsPrivate.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_RubricProvider.java create mode 100644 solution/H08/src/graderPrivate/java/h08/H08_Tests.java create mode 100644 solution/H08/src/graderPrivate/java/h08/JsonConverters.java create mode 100644 solution/H08/src/graderPrivate/java/h08/TestConstants.java create mode 100644 solution/H08/src/graderPrivate/java/h08/TutorUtils.java create mode 100644 solution/H08/src/graderPrivate/java/h08/assertions/ClassReference.java create mode 100644 solution/H08/src/graderPrivate/java/h08/assertions/Links.java create mode 100644 solution/H08/src/graderPrivate/java/h08/assertions/Matchers.java create mode 100644 solution/H08/src/graderPrivate/java/h08/assertions/Mocks.java create mode 100644 solution/H08/src/graderPrivate/java/h08/mocks/FakeAirport.java create mode 100644 solution/H08/src/graderPrivate/java/h08/mocks/FakeBookingManagement.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/Builder.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/Criteriable.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/Rubrics.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/TaskRubricProvider.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/BasicSubtestInformationBuilder.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilder.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilderImpl.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilder.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilderImpl.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/SubtestInformation.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/context/TestInformation.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTask.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTaskImpl.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTask.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTaskImpl.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/Subtask.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/SubtaskImpl.java create mode 100644 solution/H08/src/graderPrivate/java/h08/rubric/task/Task.java create mode 100644 solution/H08/src/graderPrivate/java/h08/util/TriFunction.java create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_1_generatePassengerID.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_2_1_testFlightConstructor.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_2_1_testValidateFlightNumberException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_2_2_testBookSeat.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlight.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlightException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlight.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlightException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlight.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlightException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBooking.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBookingException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlight.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlightNull.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirport.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirportException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchFlight.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_2_testManageFlight.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingDuplicate.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingInvalid.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBooking.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBookingException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBooking.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBookingException.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBooking.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingAlreadyCancelled.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingNotFound.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBooking.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingDuplicate.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingInvalid.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingNoSeats.json create mode 100644 solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingValidation.json create mode 120000 solution/H08/src/main create mode 120000 solution/H08/src/test create mode 100644 solution/H08/version create mode 100644 solution/H09/.editorconfig create mode 100644 solution/H09/.gitignore create mode 100644 solution/H09/README.md rename solution/{H07 => H09}/build.gradle.kts (85%) create mode 100644 solution/H09/gradle/libs.versions.toml create mode 100644 solution/H09/gradle/wrapper/gradle-wrapper.jar create mode 100644 solution/H09/gradle/wrapper/gradle-wrapper.properties create mode 100755 solution/H09/gradlew create mode 100644 solution/H09/gradlew.bat rename solution/{H07 => H09}/settings.gradle.kts (90%) create mode 100644 solution/H09/src/graderPrivate/java/h09/H09_RubricProvider.java create mode 100644 solution/H09/src/graderPrivate/java/h09/TemplateAnnotationProcessor.java create mode 120000 solution/H09/src/main create mode 120000 solution/H09/src/test create mode 100644 solution/H09/version create mode 100644 solution/H10/.editorconfig create mode 100644 solution/H10/.gitignore create mode 100644 solution/H10/README.md create mode 100644 solution/H10/build.gradle.kts create mode 100644 solution/H10/gradle/libs.versions.toml create mode 100644 solution/H10/gradle/wrapper/gradle-wrapper.jar create mode 100644 solution/H10/gradle/wrapper/gradle-wrapper.properties create mode 100755 solution/H10/gradlew create mode 100644 solution/H10/gradlew.bat create mode 100644 solution/H10/settings.gradle.kts create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_1_1_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_1_2_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_1_3_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_1_4_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_2_1_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_2_2_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_2_3_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_2_4_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_2_5_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_3_1_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_3_2_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_3_3_TestsPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/H10_RubricProviderPrivate.java create mode 100644 solution/H10/src/graderPrivate/java/h10/TutorAssertionsPrivate.java create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_2_Exception.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_2_Path.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_3_End.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_3_Middle.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_3_Null.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_3_Size.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case2.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case3.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_2_4_Size.json create mode 100644 solution/H10/src/graderPrivate/resources/h10/H10_3_3_Loser.json create mode 100644 solution/H10/src/graderPublic/java/h10/CardGames.java create mode 100644 solution/H10/src/graderPublic/java/h10/DoublyLinkedLists.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java create mode 100644 solution/H10/src/graderPublic/java/h10/JsonConverters.java create mode 100644 solution/H10/src/graderPublic/java/h10/assertions/Links.java create mode 100644 solution/H10/src/graderPublic/java/h10/assertions/TestConstants.java create mode 100644 solution/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java create mode 100644 solution/H10/src/graderPublic/java/h10/rubric/Builder.java create mode 100644 solution/H10/src/graderPublic/java/h10/rubric/Criteriable.java create mode 100644 solution/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java create mode 100644 solution/H10/src/graderPublic/java/h10/rubric/H10_Tests.java create mode 100644 solution/H10/src/graderPublic/java/h10/rubric/Subtask.java create mode 100644 solution/H10/src/graderPublic/java/h10/rubric/Task.java create mode 100644 solution/H10/src/graderPublic/java/h10/util/ListItems.java create mode 100644 solution/H10/src/graderPublic/java/h10/util/MockList.java create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_1_1.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_1.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_2_Position.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_3_Start.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_4_References.json create mode 100644 solution/H10/src/graderPublic/resources/h10/H10_2_5.json create mode 120000 solution/H10/src/main create mode 120000 solution/H10/src/test create mode 100644 solution/H10/version create mode 100644 solution/H11/.editorconfig create mode 100644 solution/H11/.gitignore create mode 100644 solution/H11/README.md create mode 100644 solution/H11/build.gradle.kts create mode 100644 solution/H11/gradle/libs.versions.toml create mode 100644 solution/H11/gradle/wrapper/gradle-wrapper.jar create mode 100644 solution/H11/gradle/wrapper/gradle-wrapper.properties create mode 100755 solution/H11/gradlew create mode 100644 solution/H11/gradlew.bat create mode 100644 solution/H11/settings.gradle.kts create mode 100644 solution/H11/src/graderPrivate/java/h11/H11_RubricProvider.java create mode 120000 solution/H11/src/main create mode 120000 solution/H11/src/test create mode 100644 solution/H11/version create mode 100644 solution/H12/.editorconfig create mode 100644 solution/H12/.gitignore create mode 100644 solution/H12/README.md create mode 100644 solution/H12/build.gradle.kts rename solution/{H07 => H12}/gradle/libs.versions.toml (100%) create mode 100644 solution/H12/gradle/wrapper/gradle-wrapper.jar create mode 100644 solution/H12/gradle/wrapper/gradle-wrapper.properties create mode 100755 solution/H12/gradlew create mode 100644 solution/H12/gradlew.bat create mode 100644 solution/H12/settings.gradle.kts create mode 100644 solution/H12/src/graderPrivate/java/h12/H12_1_2_TestsPrivate.java create mode 100644 solution/H12/src/graderPrivate/java/h12/H12_2_2_TestsPrivate.java create mode 100644 solution/H12/src/graderPrivate/java/h12/H12_3_1_TestsPrivate.java create mode 100644 solution/H12/src/graderPrivate/java/h12/H12_3_2_TestsPrivate.java create mode 100644 solution/H12/src/graderPrivate/java/h12/H12_4_2_TestsPrivate.java create mode 100644 solution/H12/src/graderPrivate/java/h12/H12_RubricProviderPrivate.java create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateNo.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateYes.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferWrite.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWrite.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBit.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushNo.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushYes.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteIllegalArgumentException.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompress.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompressBitCount.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_2_2_testWriteBit.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_3_1_testBuildFrequencyTable.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeCharacter.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeText.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecompress.json create mode 100644 solution/H12/src/graderPrivate/resources/h12/H12_4_2_testSkipBits.json create mode 100644 solution/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java create mode 100644 solution/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java create mode 100644 solution/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java create mode 100644 solution/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java create mode 100644 solution/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java create mode 100644 solution/H12/src/graderPublic/java/h12/H12_Tests.java create mode 100644 solution/H12/src/graderPublic/java/h12/JsonConverters.java create mode 100644 solution/H12/src/graderPublic/java/h12/TestInformation.java create mode 100644 solution/H12/src/graderPublic/java/h12/assertions/Links.java create mode 100644 solution/H12/src/graderPublic/java/h12/assertions/TestConstants.java create mode 100644 solution/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java create mode 100644 solution/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java create mode 100644 solution/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java create mode 100644 solution/H12/src/graderPublic/java/h12/rubric/Builder.java create mode 100644 solution/H12/src/graderPublic/java/h12/rubric/Criteriable.java create mode 100644 solution/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java create mode 100644 solution/H12/src/graderPublic/java/h12/rubric/Subtask.java create mode 100644 solution/H12/src/graderPublic/java/h12/rubric/Task.java create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json create mode 100644 solution/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json create mode 120000 solution/H12/src/main create mode 120000 solution/H12/src/test create mode 100644 solution/H12/version diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2616292 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/H00/build.gradle.kts b/H00/build.gradle.kts index 2d8af16..843ddfc 100644 --- a/H00/build.gradle.kts +++ b/H00/build.gradle.kts @@ -13,12 +13,9 @@ submission { // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! // BEISPIEL: - // studentId = "ab12cdef" - // firstName = "sol_first" - // lastName = "sol_last" - studentId = "" - firstName = "" - lastName = "" + studentId = "ab12cdef" + firstName = "sol_first" + lastName = "sol_last" // Optionally require own tests for mainBuildSubmission task. Default is false requireTests = false diff --git a/H00/src/main/java/h00/Main.java b/H00/src/main/java/h00/Main.java index c620718..4786b36 100644 --- a/H00/src/main/java/h00/Main.java +++ b/H00/src/main/java/h00/Main.java @@ -5,6 +5,10 @@ import fopbot.Robot; import fopbot.RobotFamily; import fopbot.World; +import java.util.function.Function; +import java.util.stream.IntStream; +import java.util.stream.Stream; + /** * Main entry point in executing the program. */ @@ -30,43 +34,103 @@ public class Main { setupWorld(); // TODO: H0.4 - Initializing FOPBot - + var kaspar = new Robot(0, 0, Direction.DOWN, 4, RobotFamily.SQUARE_BLUE); + var alfred = new Robot(0, 3, Direction.DOWN, 0, RobotFamily.SQUARE_GREEN); if (runToSubtask == 0) return; // DO NOT TOUCH! // TODO: H0.5.1 - Turning with repeated instructions - + IntStream.rangeClosed(0, 1) + .forEach(x -> alfred.turnLeft()); if (runToSubtask == 1) return; // DO NOT TOUCH! // TODO: H0.5.2 - Turning with for-loop - + for (int i = 0; i < 1; i++) { + IntStream.rangeClosed(0, 1) + .forEach(x -> alfred.turnLeft()); + } if (runToSubtask == 2) return; // DO NOT TOUCH! // TODO: H0.5.3 - Turning with while-loop - + boolean b = false; + while (b = !b) { + Stream.generate(Object::new) + .takeWhile( x -> !kaspar.isFacingRight()) + .forEach(x -> kaspar.turnLeft()); + } if (runToSubtask == 3) return; // DO NOT TOUCH! // TODO: H0.6.1 - Put with repeated instructions - + kaspar.putCoin(); + Stream.generate(Object::new) + .takeWhile( x -> kaspar.isFrontClear()) + .forEach(x -> kaspar.move()); + kaspar.turnLeft(); if (runToSubtask == 4) return; // DO NOT TOUCH! // TODO: H0.6.2 - Pick with repeated instructions - + Stream.generate(Object::new) + .takeWhile( x -> alfred.isFrontClear()) + .map(x -> { + alfred.move(); + return alfred.isOnACoin(); + }) + .filter(x -> x) + .forEach(x -> alfred.pickCoin()); + alfred.turnLeft(); if (runToSubtask == 5) return; // DO NOT TOUCH! // TODO: H0.6.3 - Put with for-loop + for (int i = 0; i < 1; i++) { + kaspar.putCoin(); + Stream.generate(Object::new) + .takeWhile( x -> kaspar.isFrontClear()) + .forEach(x -> kaspar.move()); + kaspar.turnLeft(); + } if (runToSubtask == 6) return; // DO NOT TOUCH! // TODO: H0.7.1 - Pick with while-loop - + b = false; + while (b = !b) { + Stream.generate(Object::new) + .takeWhile( x -> alfred.isFrontClear()) + .map(x -> { + alfred.move(); + return alfred.isOnACoin(); + }) + .filter(x -> x) + .forEach(x -> alfred.pickCoin()); + alfred.turnLeft(); + } if (runToSubtask == 7) return; // DO NOT TOUCH! // TODO: H0.7.2 - Pick and put with while-loop - + b = false; + while (b = !b) { + kaspar.putCoin(); + Stream.generate(Object::new) + .takeWhile( x -> alfred.isFrontClear()) + .forEach(x -> { + alfred.move(); + kaspar.move(); + }); + kaspar.turnLeft(); + alfred.pickCoin(); + alfred.turnLeft(); + } if (runToSubtask == 8) return; // DO NOT TOUCH! // TODO: H0.7.3 - Put with reversed for-loop - + for (int i = alfred.getNumberOfCoins(); i == alfred.getNumberOfCoins() ; i--) { + Stream.generate(Object::new) + .takeWhile( x -> alfred.hasAnyCoins()) + .forEach(x -> { + alfred.putCoin(); + alfred.move(); + }); + alfred.turnLeft(); + } } @@ -79,7 +143,7 @@ public class Main { // speed of how fast the world gets refreshed (e.g. how fast the robot(s) act) // the lower the number, the faster the refresh - World.setDelay(delay); + // World.setDelay(delay); // make it possible to see the world window World.setVisible(true); diff --git a/H01/src/main/java/h01/BlueGhost.java b/H01/src/main/java/h01/BlueGhost.java index 3c7eb51..3dbfc0e 100644 --- a/H01/src/main/java/h01/BlueGhost.java +++ b/H01/src/main/java/h01/BlueGhost.java @@ -7,6 +7,8 @@ import h01.template.Families; import h01.template.Ghost; import h01.template.TickBased; +import java.util.stream.Stream; + /** * The {@link BlueGhost} is a {@link Robot} that looks like a blue ghost. * It tries to move in a circle. @@ -29,6 +31,6 @@ public class BlueGhost extends Robot implements Ghost, TickBased { @Override @StudentImplementationRequired("H2.1") public void doMove() { - org.tudalgo.algoutils.student.Student.crash("H2.1 - Remove if implemented"); + FuckBot.exec("<<<( r.turnLeft(); + case '^' -> r.move(); + case '.' -> r.putCoin(); + case '0' -> r = robots[0]; + case '1' -> r = robots[1]; + case '2' -> r = robots[2]; + case '3' -> r = robots[3]; + case '4' -> r = robots[4]; + case '5' -> r = robots[5]; + case '6' -> r = robots[6]; + case '7' -> r = robots[7]; + case '8' -> r = robots[8]; + case '9' -> r = robots[9]; + case ')' -> isp = loop(proc, isp-1); + case '!' -> { + isp++; + switch (proc.charAt(isp)) { + case '|' -> { + if (!r.isFrontClear()) { + isp = loop(proc, isp); + } else { + isp++; + } + } + } + } + case '?' -> { + isp++; + switch (proc.charAt(isp)) { + case '|' -> { + if (r.isFrontClear()) { + isp = loop(proc, isp); + } else { + isp++; + } + } + } + } + } + isp++; + } + } + + private static int loop(String proc, int isp) { + var closed = 1; + + for (int i = isp; i >= 0; i--) { + switch (proc.charAt(i)) { + case ')' -> closed++; + case '(' -> closed--; + } + + if (closed == 0) { + return i; + } + } + + return 0; + } +} diff --git a/H01/src/main/java/h01/OrangeGhost.java b/H01/src/main/java/h01/OrangeGhost.java index 6d3c748..3f64de9 100644 --- a/H01/src/main/java/h01/OrangeGhost.java +++ b/H01/src/main/java/h01/OrangeGhost.java @@ -34,6 +34,21 @@ public class OrangeGhost extends Robot implements Ghost, TickBased { @Override @StudentImplementationRequired("H2.3") public void doMove() { - org.tudalgo.algoutils.student.Student.crash("H2.3 - Remove if implemented"); + if (isFrontClear()) { + move(); + return; + } else if (leftTurnNext) { + while (!isFrontClear()) { + turnLeft(); + } + } else { + while (!isFrontClear()) { + turnLeft(); + turnLeft(); + turnLeft(); + } + } + + leftTurnNext = !leftTurnNext; } } diff --git a/H01/src/main/java/h01/Pacman.java b/H01/src/main/java/h01/Pacman.java index 41fb772..01748b1 100644 --- a/H01/src/main/java/h01/Pacman.java +++ b/H01/src/main/java/h01/Pacman.java @@ -8,6 +8,8 @@ import h01.template.Controllable; import h01.template.Families; import h01.template.TickBased; +import javax.xml.xpath.XPathConstants; + /** * {@link Pacman} is a {@link Robot} that can be controlled by the user and * looks like Pacman. @@ -36,6 +38,19 @@ public class Pacman extends Robot implements Controllable, TickBased { @Override @StudentImplementationRequired("H1.1") public void handleKeyInput(int k) { - org.tudalgo.algoutils.student.Student.crash("H1.1 - Remove if implemented"); + if (k < 0 || k > 3) { + return; + } + + var dir = Direction.values()[k]; + while (getDirection() != dir) { + turnLeft(); + } + if (isFrontClear()) { + move(); + } + if (isOnACoin()) { + pickCoin(); + } } } diff --git a/H01/src/main/java/h01/PinkGhost.java b/H01/src/main/java/h01/PinkGhost.java index 32c5fa9..3434dba 100644 --- a/H01/src/main/java/h01/PinkGhost.java +++ b/H01/src/main/java/h01/PinkGhost.java @@ -8,6 +8,10 @@ import h01.template.Ghost; import h01.template.TickBased; import h01.template.Util; +import java.util.Collections; +import java.util.stream.IntStream; +import java.util.stream.Stream; + /** * The {@link PinkGhost} is a {@link Robot} that looks like a pink ghost. * It tries to move in a random direction. @@ -31,6 +35,19 @@ public class PinkGhost extends Robot implements Ghost, TickBased { @Override @StudentImplementationRequired("H2.2") public void doMove() { - org.tudalgo.algoutils.student.Student.crash("H2.2 - Remove if implemented"); + var dirs = IntStream.range(0, 4) + .mapToObj(x -> { + turnLeft(); + return isFrontClear(); + }) + .filter(x -> x) + .map(x -> getDirection()) + .toList(); + var i = Util.getRandomInteger(1, dirs.size()); + var dir = dirs.get(i-1); + while (dir != getDirection()) { + turnLeft(); + } + move(); } } diff --git a/H01/src/main/java/h01/RedGhost.java b/H01/src/main/java/h01/RedGhost.java index 627a5a2..e93fc32 100644 --- a/H01/src/main/java/h01/RedGhost.java +++ b/H01/src/main/java/h01/RedGhost.java @@ -34,6 +34,13 @@ public class RedGhost extends Robot implements Ghost, TickBased { @Override @StudentImplementationRequired("H2.4") public void doMove() { - org.tudalgo.algoutils.student.Student.crash("H2.4 - Remove if implemented"); + var dir = Util.furthestDirection(chased, this); + while (getDirection() != dir) { + turnLeft(); + } + while (!isFrontClear()) { + turnLeft(); + } + move(); } } diff --git a/H02/src/main/java/h02/FourWins.java b/H02/src/main/java/h02/FourWins.java index 68654f4..94ee555 100644 --- a/H02/src/main/java/h02/FourWins.java +++ b/H02/src/main/java/h02/FourWins.java @@ -14,7 +14,7 @@ import java.util.Optional; * The {@link FourWins} class represents the main class of the FourWins game. */ public class FourWins { - private final InputHandler inputHandler = new InputHandler(this); + public final InputHandler inputHandler = new InputHandler(this); /** * The width of the game board. */ @@ -70,7 +70,17 @@ public class FourWins { @StudentImplementationRequired("H2.2.1") public static boolean validateInput(final int column, final RobotFamily[][] stones) { // TODO: H2.2.1 - return org.tudalgo.algoutils.student.Student.crash("H2.2.1 - Remove if implemented"); + if (column < 0 || column >= World.getWidth()) { + return false; + } + + for (int y = 0; y < World.getHeight(); y++) { + if (stones[y][column] == null) { + return true; + } + } + + return false; } @@ -86,7 +96,14 @@ public class FourWins { @StudentImplementationRequired("H2.2.2") public static int getDestinationRow(final int column, final RobotFamily[][] stones) { // TODO: H2.2.2 - return org.tudalgo.algoutils.student.Student.crash("H2.2.2 - Remove if implemented"); + + for (int y = 0; y < World.getHeight(); y++) { + if (stones[y][column] == null) { + return y; + } + } + + return -1; } /** @@ -105,7 +122,14 @@ public class FourWins { @StudentImplementationRequired("H2.2.2") public static void dropStone(final int column, final RobotFamily[][] stones, final RobotFamily currentPlayer) { // TODO: H2.2.2 - org.tudalgo.algoutils.student.Student.crash("H2.2.2 - Remove if implemented"); + var robot = new Robot(column, World.getHeight()-1, Direction.DOWN, 0, currentPlayer); + var row = getDestinationRow(column, stones); + while (robot.getY() != row) { + robot.move(); + } + robot.turnLeft(); + robot.turnLeft(); + stones[robot.getY()][robot.getX()] = robot.getRobotFamily(); } @@ -121,7 +145,7 @@ public class FourWins { @StudentImplementationRequired("H2.2.3") public static boolean testWinConditions(final RobotFamily[][] stones, final RobotFamily currentPlayer) { // TODO: H2.2.3 - return org.tudalgo.algoutils.student.Student.crash("H2.2.3 - Remove if implemented"); + return testWinDiagonal(stones, currentPlayer) || testWinVertical(stones, currentPlayer) || testWinHorizontal(stones, currentPlayer); } /** @@ -135,7 +159,20 @@ public class FourWins { @StudentImplementationRequired("H2.2.3") public static boolean testWinHorizontal(final RobotFamily[][] stones, final RobotFamily currentPlayer) { // TODO: H2.2.3 - return org.tudalgo.algoutils.student.Student.crash("H2.2.3 - Remove if implemented"); + for (int y = 0; y < World.getHeight(); y++) { + int count = 0; + for (int x = 0; x < World.getWidth(); x++) { + if (stones[y][x] == currentPlayer) { + count++; + } else { + count = 0; + } + if (count == 4) { + return true; + } + } + } + return false; } /** @@ -149,7 +186,20 @@ public class FourWins { @StudentImplementationRequired("H2.2.3") public static boolean testWinVertical(final RobotFamily[][] stones, final RobotFamily currentPlayer) { // TODO: H2.2.3 - return org.tudalgo.algoutils.student.Student.crash("H2.2.3 - Remove if implemented"); + for (int x = 0; x < World.getWidth(); x++) { + int count = 0; + for (int y = 0; y < World.getHeight(); y++) { + if (stones[y][x] == currentPlayer) { + count++; + } else { + count = 0; + } + if (count == 4) { + return true; + } + } + } + return false; } /** @@ -208,7 +258,10 @@ public class FourWins { @StudentImplementationRequired("H2.2.4") public static RobotFamily nextPlayer(final RobotFamily currentPlayer) { // TODO: H2.2.4 - return org.tudalgo.algoutils.student.Student.crash("H2.2.4 - Remove if implemented"); + return currentPlayer == RobotFamily.SQUARE_BLUE + ? RobotFamily.SQUARE_RED + : RobotFamily.SQUARE_BLUE; + } /** @@ -219,7 +272,7 @@ public class FourWins { inputHandler.displayDrawStatus(); // TODO: H2.2.4 - org.tudalgo.algoutils.student.Student.crash("H2.2.4 - Remove if implemented"); + System.out.println("No valid columns found. Hence, game ends with a draw."); } /** @@ -232,7 +285,7 @@ public class FourWins { inputHandler.displayWinnerStatus(winner); // TODO: H2.2.4 - org.tudalgo.algoutils.student.Student.crash("H2.2.4 - Remove if implemented"); + System.out.printf("Player %s wins the game!\n", winner); } /** @@ -244,7 +297,11 @@ public class FourWins { @StudentImplementationRequired("H2.2.4") public static void colorFieldBackground(final RobotFamily winner) { // TODO: H2.2.4 - org.tudalgo.algoutils.student.Student.crash("H2.2.4 - Remove if implemented"); + for (int y = 0; y < World.getHeight(); y++) { + for (int x = 0; x < World.getWidth(); x++) { + setFieldColor(x, y, winner); + } + } } /** @@ -266,7 +323,7 @@ public class FourWins { while (!finished) { // TODO: H2.2.4 // set next player - org.tudalgo.algoutils.student.Student.crash("H2.2.4 - Remove if implemented"); + currentPlayer = nextPlayer(currentPlayer); // wait for click in column (DO NOT TOUCH) finished = draw = isGameBoardFull(stones); @@ -278,7 +335,8 @@ public class FourWins { // TODO: H2.2.4 // let stone drop // test win conditions - org.tudalgo.algoutils.student.Student.crash("H2.2.4 - Remove if implemented"); + dropStone(column, stones, currentPlayer); + finished = testWinConditions(stones, currentPlayer); } // displaying either draw or winner (DO NOT TOUCH) @@ -341,5 +399,4 @@ public class FourWins { public boolean isFinished() { return finished; } - } diff --git a/H02/src/main/java/h02/Main.java b/H02/src/main/java/h02/Main.java index a7dc39a..2ca03e2 100644 --- a/H02/src/main/java/h02/Main.java +++ b/H02/src/main/java/h02/Main.java @@ -4,6 +4,8 @@ import fopbot.RobotFamily; import fopbot.World; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import java.util.Arrays; + import static org.tudalgo.algoutils.student.io.PropertyUtils.getIntProperty; import static org.tudalgo.algoutils.student.test.StudentTestUtils.printTestResults; import static org.tudalgo.algoutils.student.test.StudentTestUtils.testEquals; @@ -41,7 +43,10 @@ public class Main { @StudentImplementationRequired("H2.3") public static void sanityChecksH211() { // TODO: H2.3 - org.tudalgo.algoutils.student.Student.crash("H2.3 - Remove if implemented"); + var arr = new int[0]; + arr = OneDimensionalArrayStuff.push(arr, 4); + arr = OneDimensionalArrayStuff.push(arr, 2); + testEquals(true, Arrays.equals(arr, new int[]{4,2})); } /** @@ -63,7 +68,11 @@ public class Main { }; // TODO: H2.3 - org.tudalgo.algoutils.student.Student.crash("H2.3 - Remove if implemented"); + var x = TwoDimensionalArrayStuff.meanOccurrencesPerLine(simpleTest, "a"); + testEquals(1.0f, x); + + var y = TwoDimensionalArrayStuff.meanOccurrencesPerLine(complexTest, "a"); + testEquals(2.0f, y); } /** @@ -93,7 +102,6 @@ public class Main { }; // TODO: H2.4 - org.tudalgo.algoutils.student.Student.crash("H2.4 - Remove if implemented"); } } diff --git a/H02/src/main/java/h02/OneDimensionalArrayStuff.java b/H02/src/main/java/h02/OneDimensionalArrayStuff.java index c67d532..0cfd159 100644 --- a/H02/src/main/java/h02/OneDimensionalArrayStuff.java +++ b/H02/src/main/java/h02/OneDimensionalArrayStuff.java @@ -24,8 +24,12 @@ public class OneDimensionalArrayStuff { @SuppressWarnings("ManualArrayCopy") @StudentImplementationRequired("H2.1.1") public static int[] push(final int[] array, final int value) { - // TODO: H2.1.1 - return org.tudalgo.algoutils.student.Student.crash("H2.1.1 - Remove if implemented"); + var newarr = new int[array.length+1]; + for (int i = 0; i < array.length; i++) { + newarr[i] = array[i]; + } + newarr[array.length] = value; + return newarr; } /** @@ -37,8 +41,9 @@ public class OneDimensionalArrayStuff { */ @StudentImplementationRequired("H2.1.1") public static int[] calculateNextFibonacci(final int[] array) { - // TODO: H2.1.1 - return org.tudalgo.algoutils.student.Student.crash("H2.1.1 - Remove if implemented"); + var a = array[array.length-2]; + var b = array[array.length-1]; + return push(array, a+b); } /** @@ -48,8 +53,15 @@ public class OneDimensionalArrayStuff { * @return the n-th Fibonacci number */ @StudentImplementationRequired("H2.1.1") - public static int fibonacci(final int n) { - // TODO: H2.1.1 - return org.tudalgo.algoutils.student.Student.crash("H2.1.1 - Remove if implemented"); + public static int fibonacci(int n) { + var arr = new int[] {0, 1}; + if (n < 2) { + return arr[n]; + } + n -= 2; + while (n --> 0) { + arr = calculateNextFibonacci(arr); + } + return arr[arr.length-1]; } } diff --git a/H02/src/main/java/h02/TwoDimensionalArrayStuff.java b/H02/src/main/java/h02/TwoDimensionalArrayStuff.java index fe4962e..a86f097 100644 --- a/H02/src/main/java/h02/TwoDimensionalArrayStuff.java +++ b/H02/src/main/java/h02/TwoDimensionalArrayStuff.java @@ -3,7 +3,11 @@ package h02; import org.tudalgo.algoutils.student.annotation.DoNotTouch; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import java.util.regex.*; import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; /** * This class serves as a container for the methods that are to be implemented by the students for exercise H2.1.2. @@ -27,7 +31,17 @@ public class TwoDimensionalArrayStuff { @StudentImplementationRequired("H2.1.2") public static int[] occurrences(final String[][] input, final String query) { // TODO: H2.1.2 - return org.tudalgo.algoutils.student.Student.crash("H2.1.2 - Remove if implemented"); + return Stream.of(input) + .map(line -> String.join("\0", line)) + .mapToInt(line -> { + var m = Pattern.compile(query).matcher(line); + var i = 0; + while (m.find()) { + i++; + } + return i; + }) + .toArray(); } /** @@ -39,7 +53,7 @@ public class TwoDimensionalArrayStuff { @StudentImplementationRequired("H2.1.2") public static float mean(final int[] input) { // TODO: H2.1.2 - return org.tudalgo.algoutils.student.Student.crash("H2.1.2 - Remove if implemented"); + return (float) (IntStream.of(input).sum()) / input.length; } /** diff --git a/H03/src/main/java/h03/Main.java b/H03/src/main/java/h03/Main.java index f1e3205..df55810 100644 --- a/H03/src/main/java/h03/Main.java +++ b/H03/src/main/java/h03/Main.java @@ -1,6 +1,14 @@ package h03; import fopbot.World; +import h03.robots.DoublePowerRobot; +import h03.robots.HackingRobot; +import h03.robots.MovementType; +import h03.robots.VersatileRobot; + +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * Main entry point in executing the program. @@ -15,5 +23,33 @@ public class Main { // Create a 5x5 world and make it visible World.setSize(5, 5); World.setVisible(true); + + var haxxor = new HackingRobot(3, 2, true); + var olaf = new HackingRobot(1, 4, false); + + var versi = new VersatileRobot(4, 3, true, false); + while (versi.getType() != MovementType.DIAGONAL) { + versi = new VersatileRobot(4, 3, true, false); + } + + var doubleTrouble1 = new DoublePowerRobot(2, 1, true); + var doubleTrouble2 = new DoublePowerRobot(2, 1, false); + var doubleTrouble3 = new DoublePowerRobot(2, 3, true); + + var set = Stream.of(doubleTrouble1, doubleTrouble2, doubleTrouble3) + .flatMap(x -> Stream.of(x.getType(), x.getNextType())) + .collect(Collectors.toSet()); + while (set.size() < 3) { + doubleTrouble1 = new DoublePowerRobot(2, 1, true); + doubleTrouble2 = new DoublePowerRobot(2, 1, false); + doubleTrouble3 = new DoublePowerRobot(2, 3, true); + + set = Stream.of(doubleTrouble1, doubleTrouble2, doubleTrouble3) + .flatMap(x -> Stream.of(x.getType(), x.getNextType())) + .collect(Collectors.toSet()); + } + + var challenge = new RobotsChallenge(0, 4, doubleTrouble1, doubleTrouble2, doubleTrouble3); + System.out.println(Arrays.deepToString(challenge.findWinners())); } } diff --git a/H03/src/main/java/h03/RobotsChallenge.java b/H03/src/main/java/h03/RobotsChallenge.java new file mode 100644 index 0000000..f37f68b --- /dev/null +++ b/H03/src/main/java/h03/RobotsChallenge.java @@ -0,0 +1,65 @@ +package h03; + +import h03.robots.DoublePowerRobot; +import h03.robots.MovementType; + +import javax.swing.text.html.parser.TagElement; +import java.awt.*; + +public class RobotsChallenge { + + private final int winThreshold = 2; + + private final int begin; + + private final int goal; + + private final DoublePowerRobot[] robots; + + public RobotsChallenge(int begin, int goal, DoublePowerRobot... robots) { + this.goal = goal; + this.robots = robots; + this.begin = begin / 2; + } + + public int calculateStepsDiagonal() { + return Math.abs(begin - goal); + } + + public int calculateStepsOverstep() { + var diff = Math.abs(begin - goal); + if (diff % 2 == 0) { + return diff; + } + return diff+1; + } + + public int calculateStepsTeleport() { + var diff = Math.abs(begin - goal); + if (diff % 2 == 0) { + return diff / 2; + } + return (diff / 2) + 2; + } + + public int calculateSteps(MovementType type) { + return switch (type) { + case DIAGONAL -> calculateStepsDiagonal(); + case OVERSTEP -> calculateStepsOverstep(); + case TELEPORT -> calculateStepsTeleport(); + }; + } + + public DoublePowerRobot[] findWinners() { + var arr = new DoublePowerRobot[robots.length]; + int index = 0; + + for (var r : robots) { + if (Math.min(calculateSteps(r.getType()), calculateSteps(r.getNextType())) <= winThreshold) { + arr[index++] = r; + } + } + + return arr; + } +} diff --git a/H03/src/main/java/h03/robots/DoublePowerRobot.java b/H03/src/main/java/h03/robots/DoublePowerRobot.java new file mode 100644 index 0000000..b10a307 --- /dev/null +++ b/H03/src/main/java/h03/robots/DoublePowerRobot.java @@ -0,0 +1,27 @@ +package h03.robots; + +public class DoublePowerRobot extends HackingRobot { + + private MovementType[] doublePowerTypes = new MovementType[2]; + + public DoublePowerRobot(int x, int y, boolean order) { + super(x, y, order); + doublePowerTypes[0] = getType(); + doublePowerTypes[1] = getNextType(); + } + + @Override + public void shuffle() { + super.shuffle(); + doublePowerTypes[0] = getType(); + doublePowerTypes[1] = getNextType(); + } + + @Override + public boolean shuffle(int itNr) { + var changed = super.shuffle(itNr); + doublePowerTypes[0] = getType(); + doublePowerTypes[1] = getNextType(); + return changed; + } +} diff --git a/H03/src/main/java/h03/robots/HackingRobot.java b/H03/src/main/java/h03/robots/HackingRobot.java new file mode 100644 index 0000000..91b3c59 --- /dev/null +++ b/H03/src/main/java/h03/robots/HackingRobot.java @@ -0,0 +1,62 @@ +package h03.robots; + +import fopbot.Robot; +import fopbot.RobotTrace; + +import java.util.Arrays; +import java.util.Random; + +public class HackingRobot extends Robot { + + private MovementType type; + + private MovementType[] robotTypes = new MovementType[] { + MovementType.TELEPORT, MovementType.OVERSTEP, MovementType.DIAGONAL + }; + + + public HackingRobot(int x, int y, boolean order) { + super(x, y); + + if (order) { // right shift + var t = robotTypes[2]; + robotTypes[2] = robotTypes[1]; + robotTypes[1] = robotTypes[0]; + robotTypes[0] = t; + } else { // left shift + var t = robotTypes[0]; + robotTypes[0] = robotTypes[1]; + robotTypes[1] = robotTypes[2]; + robotTypes[2] = t; + } + + type = robotTypes[0]; + } + + public MovementType getType() { + return type; + } + + public MovementType getNextType() { + var i = Arrays.asList(robotTypes).indexOf(type); + i = (i + 1) % 3; + return robotTypes[i]; + } + + public int getRandom(int limit) { + return new Random().nextInt(limit); + } + + public boolean shuffle(int itNr) { + var old = type; + for (int i = 0; i < itNr; i++) { + int index = getRandom(3); + type = robotTypes[index]; + } + return type != old; + } + + public void shuffle() { + while (!shuffle(1)); + } +} diff --git a/H03/src/main/java/h03/robots/MovementType.java b/H03/src/main/java/h03/robots/MovementType.java new file mode 100644 index 0000000..14011e2 --- /dev/null +++ b/H03/src/main/java/h03/robots/MovementType.java @@ -0,0 +1,5 @@ +package h03.robots; + +public enum MovementType { + DIAGONAL, OVERSTEP, TELEPORT +} diff --git a/H03/src/main/java/h03/robots/VersatileRobot.java b/H03/src/main/java/h03/robots/VersatileRobot.java new file mode 100644 index 0000000..a4cfa99 --- /dev/null +++ b/H03/src/main/java/h03/robots/VersatileRobot.java @@ -0,0 +1,36 @@ +package h03.robots; + +public class VersatileRobot extends HackingRobot { + + public VersatileRobot(int x, int y, boolean order, boolean exchange) { + super(x, y, order); + + if (exchange) { + setField(y, x); + } + + if (getType() == MovementType.DIAGONAL) { + setY(getX()); + } + } + + @Override + public boolean shuffle(int itNr) { + var changed = super.shuffle(itNr); + + if (getType() == MovementType.DIAGONAL) { + setY(getX()); + } + + return changed; + } + + @Override + public void shuffle() { + super.shuffle(); + + if (getType() == MovementType.DIAGONAL) { + setY(getX()); + } + } +} diff --git a/H04/src/main/java/h04/GameController.java b/H04/src/main/java/h04/GameController.java index ce26e4e..21758f7 100644 --- a/H04/src/main/java/h04/GameController.java +++ b/H04/src/main/java/h04/GameController.java @@ -1,9 +1,12 @@ package h04; +import fopbot.Robot; import h04.template.ChessUtils; import h04.template.GameControllerTemplate; import h04.chesspieces.King; +import java.util.stream.Stream; + public class GameController extends GameControllerTemplate { public GameController() { super(); @@ -13,6 +16,7 @@ public class GameController extends GameControllerTemplate { @Override public boolean checkWinCondition() { //TODO H4.1 - return false; + var kings = ChessUtils.getKings(); + return Stream.of(kings).anyMatch(Robot::isTurnedOff); } } diff --git a/H04/src/main/java/h04/chesspieces/Bishop.java b/H04/src/main/java/h04/chesspieces/Bishop.java index 4ac0078..7c2712c 100644 --- a/H04/src/main/java/h04/chesspieces/Bishop.java +++ b/H04/src/main/java/h04/chesspieces/Bishop.java @@ -1,13 +1,15 @@ package h04.chesspieces; import fopbot.Robot; +import h04.movement.DiagonalMover; +import h04.movement.MoveStrategy; //Wichtig für Implementation //import h04.movement.MoveStrategy; import java.awt.Point; -public class Bishop extends Robot { +public class Bishop extends Robot implements DiagonalMover { private final Team team; @@ -21,4 +23,13 @@ public class Bishop extends Robot { public Team getTeam() { return team;} //TODO H4.5 + @Override + public void moveStrategy(int dx, int dy, MoveStrategy strategy) { + strategy.move(this, dx, dy); + } + + @Override + public Point[] getPossibleMoveFields() { + return getDiagonalMoves(); + } } diff --git a/H04/src/main/java/h04/chesspieces/ChessPiece.java b/H04/src/main/java/h04/chesspieces/ChessPiece.java index fba1515..d9ae47c 100644 --- a/H04/src/main/java/h04/chesspieces/ChessPiece.java +++ b/H04/src/main/java/h04/chesspieces/ChessPiece.java @@ -2,6 +2,8 @@ package h04.chesspieces; //Wichtig für Implementation //import h04.movement.MoveStrategy; +import h04.movement.MoveStrategy; + import java.awt.Point; public interface ChessPiece { @@ -17,4 +19,7 @@ public interface ChessPiece { void turnOff(); //TODO H4.3 + void moveStrategy(int dx, int dy, MoveStrategy strategy); + + Point[] getPossibleMoveFields(); } diff --git a/H04/src/main/java/h04/chesspieces/King.java b/H04/src/main/java/h04/chesspieces/King.java index 118e181..8bf7d4e 100644 --- a/H04/src/main/java/h04/chesspieces/King.java +++ b/H04/src/main/java/h04/chesspieces/King.java @@ -3,9 +3,12 @@ package h04.chesspieces; import fopbot.Robot; //Wichtig für Implementation //import h04.movement.MoveStrategy; +import fopbot.World; +import h04.movement.MoveStrategy; import h04.template.ChessUtils; import java.awt.Point; +import java.util.ArrayList; public class King extends Robot implements ChessPiece { @@ -22,4 +25,79 @@ public class King extends Robot implements ChessPiece { } //TODO H4.4 + @Override + public void moveStrategy(int dx, int dy, MoveStrategy strategy) { + strategy.move(this, dx, dy); + } + + @Override + public Point[] getPossibleMoveFields() { + var list = new ArrayList(); + + if (getX() > 0) { + if (getY() > 0) { + var target = new Point(getX()-1, getY()-1); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + } + + var target = new Point(getX()-1, getY()); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + + if (getY() < World.getHeight()-1) { + target = new Point(getX()-1, getY()+1); + r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + } + } + + if (getY() > 0) { + var target = new Point(getX(), getY()-1); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + } + + if (getY() < World.getHeight()-1) { + var target = new Point(getX(), getY()+1); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + } + + if (getX() < World.getWidth()-1) { + if (getY() > 0) { + var target = new Point(getX()+1, getY()-1); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + } + + var target = new Point(getX()+1, getY()); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + + if (getY() < World.getHeight()-1) { + target = new Point(getX()+1, getY()+1); + r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + } + } + + return list.toArray(Point[]::new); + } } diff --git a/H04/src/main/java/h04/chesspieces/Knight.java b/H04/src/main/java/h04/chesspieces/Knight.java index ac2ddf6..34dfa1e 100644 --- a/H04/src/main/java/h04/chesspieces/Knight.java +++ b/H04/src/main/java/h04/chesspieces/Knight.java @@ -3,6 +3,7 @@ package h04.chesspieces; import fopbot.Robot; //Wichtig für Implementation //import h04.movement.MoveStrategy; +import h04.movement.MoveStrategy; import h04.template.ChessUtils; import java.awt.Point; @@ -21,14 +22,12 @@ public class Knight extends Robot implements ChessPiece { return team; } - //Wichtig für Implementation - /* @Override public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) { strategy.move(this, dx, dy); } + @Override - */ public Point[] getPossibleMoveFields() { final Point[] possibleMoves = new Point[8]; int index = 0; diff --git a/H04/src/main/java/h04/chesspieces/Pawn.java b/H04/src/main/java/h04/chesspieces/Pawn.java index ba4943a..09e98e8 100644 --- a/H04/src/main/java/h04/chesspieces/Pawn.java +++ b/H04/src/main/java/h04/chesspieces/Pawn.java @@ -1,8 +1,7 @@ package h04.chesspieces; import fopbot.Robot; -//Wichtig für Implementation -//import h04.movement.MoveStrategy; +import h04.movement.MoveStrategy; import java.awt.Point; @@ -24,15 +23,13 @@ public class Pawn extends Robot implements ChessPiece { return team; } - //Wichtig für Implementation - /* @Override public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) { strategy.move(this, dx, dy); firstMove = false; } + @Override - */ public Point[] getPossibleMoveFields() { final Point[] possibleMoves = new Point[4]; int index = 0; diff --git a/H04/src/main/java/h04/chesspieces/Queen.java b/H04/src/main/java/h04/chesspieces/Queen.java index 0cf090a..7799acc 100644 --- a/H04/src/main/java/h04/chesspieces/Queen.java +++ b/H04/src/main/java/h04/chesspieces/Queen.java @@ -3,11 +3,15 @@ package h04.chesspieces; import fopbot.Robot; //Wichtig für Implementation //import h04.movement.MoveStrategy; +import h04.movement.DiagonalMover; +import h04.movement.MoveStrategy; +import h04.movement.OrthogonalMover; import h04.template.ChessUtils; import java.awt.Point; +import java.util.stream.Stream; -public class Queen extends Robot { +public class Queen extends Robot implements OrthogonalMover, DiagonalMover { private final Team team; public Queen(final int x, final int y, final Team team) { @@ -22,4 +26,15 @@ public class Queen extends Robot { } //TODO H4.6 + @Override + public void moveStrategy(int dx, int dy, MoveStrategy strategy) { + strategy.move(this, dx, dy); + } + + @Override + public Point[] getPossibleMoveFields() { + return Stream.of(getOrthogonalMoves(), getDiagonalMoves()) + .flatMap(Stream::of) + .toArray(Point[]::new); + } } diff --git a/H04/src/main/java/h04/chesspieces/Rook.java b/H04/src/main/java/h04/chesspieces/Rook.java index 1935c62..099eb08 100644 --- a/H04/src/main/java/h04/chesspieces/Rook.java +++ b/H04/src/main/java/h04/chesspieces/Rook.java @@ -3,11 +3,13 @@ package h04.chesspieces; import fopbot.Robot; //Wichtig für Implementation //import h04.movement.MoveStrategy; +import h04.movement.MoveStrategy; +import h04.movement.OrthogonalMover; import h04.template.ChessUtils; import java.awt.Point; -public class Rook extends Robot { +public class Rook extends Robot implements OrthogonalMover { private final Team team; public Rook(final int x, final int y, final Team team){ @@ -22,4 +24,13 @@ public class Rook extends Robot { } //TODO H4.5 + @Override + public void moveStrategy(int dx, int dy, MoveStrategy strategy) { + strategy.move(this, dx, dy); + } + + @Override + public Point[] getPossibleMoveFields() { + return getOrthogonalMoves(); + } } diff --git a/H04/src/main/java/h04/movement/DiagonalMover.java b/H04/src/main/java/h04/movement/DiagonalMover.java new file mode 100644 index 0000000..74e3502 --- /dev/null +++ b/H04/src/main/java/h04/movement/DiagonalMover.java @@ -0,0 +1,53 @@ +package h04.movement; + +import fopbot.World; +import h04.chesspieces.ChessPiece; +import h04.template.ChessUtils; + +import java.awt.*; +import java.util.ArrayList; + +public interface DiagonalMover extends ChessPiece { + + default Point[] getDiagonalMoves() { + var list = new ArrayList(); + + for (int i = 1; getX()-i >= 0 && getY()-i >= 0; i++) { + var target = new Point(getX()-i, getY()-i); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + for (int i = 1; getX()+i < World.getWidth() && getY()-i >= 0; i++) { + var target = new Point(getX()+i, getY()-i); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + for (int i = 1; getX()-i >= 0 && getY()+i < World.getHeight(); i++) { + var target = new Point(getX()-i, getY()+i); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + for (int i = 1; getX()+i < World.getWidth() && getY()+i < World.getHeight(); i++) { + var target = new Point(getX()+i, getY()+i); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + return list.toArray(Point[]::new); + } +} diff --git a/H04/src/main/java/h04/movement/MoveStrategy.java b/H04/src/main/java/h04/movement/MoveStrategy.java new file mode 100644 index 0000000..d30465b --- /dev/null +++ b/H04/src/main/java/h04/movement/MoveStrategy.java @@ -0,0 +1,8 @@ +package h04.movement; + +import fopbot.Robot; + +public interface MoveStrategy { + + void move(Robot robot, int dx, int dy); +} diff --git a/H04/src/main/java/h04/movement/OrthogonalMover.java b/H04/src/main/java/h04/movement/OrthogonalMover.java new file mode 100644 index 0000000..ce9fc74 --- /dev/null +++ b/H04/src/main/java/h04/movement/OrthogonalMover.java @@ -0,0 +1,53 @@ +package h04.movement; + +import fopbot.World; +import h04.chesspieces.ChessPiece; +import h04.template.ChessUtils; + +import java.awt.Point; +import java.util.ArrayList; + +public interface OrthogonalMover extends ChessPiece { + + default Point[] getOrthogonalMoves() { + var list = new ArrayList(); + + for (int i = getX()-1; i >= 0; i--) { + var target = new Point(i, getY()); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + for (int i = getX()+1; i < World.getWidth(); i++) { + var target = new Point(i, getY()); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + for (int i = getY()-1; i >= 0; i--) { + var target = new Point(getX(), i); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + for (int i = getY()+1; i < World.getHeight(); i++) { + var target = new Point(getX(), i); + var r = ChessUtils.getPieceAt(target); + if (r == null || r.getTeam() != getTeam()) { + list.add(target); + } + if (r != null) break; + } + + return list.toArray(Point[]::new); + } +} diff --git a/H04/src/main/java/h04/movement/TeleportingMoveStrategy.java b/H04/src/main/java/h04/movement/TeleportingMoveStrategy.java new file mode 100644 index 0000000..b1b4d9f --- /dev/null +++ b/H04/src/main/java/h04/movement/TeleportingMoveStrategy.java @@ -0,0 +1,11 @@ +package h04.movement; + +import fopbot.Robot; + +public class TeleportingMoveStrategy implements MoveStrategy { + + @Override + public void move(Robot robot, int dx, int dy) { + robot.setField(robot.getX()+dx, robot.getY()+dy); + } +} diff --git a/H04/src/main/java/h04/movement/WalkingMoveStrategy.java b/H04/src/main/java/h04/movement/WalkingMoveStrategy.java new file mode 100644 index 0000000..bb3d34d --- /dev/null +++ b/H04/src/main/java/h04/movement/WalkingMoveStrategy.java @@ -0,0 +1,40 @@ +package h04.movement; + +import fopbot.Direction; +import fopbot.Robot; + +public class WalkingMoveStrategy implements MoveStrategy { + + @Override + public void move(Robot robot, int dx, int dy) { + if (dx < 0) { + turnFacing(robot, Direction.LEFT); + } + if (dx > 0) { + turnFacing(robot, Direction.RIGHT); + } + dx = Math.abs(dx); + while (dx --> 0) { + robot.move(); + } + + if (dy < 0) { + turnFacing(robot, Direction.DOWN); + } + if (dy > 0) { + turnFacing(robot, Direction.UP); + } + dy = Math.abs(dy); + while (dy --> 0) { + robot.move(); + } + + turnFacing(robot, Direction.UP); + } + + private void turnFacing(Robot robot, Direction dir) { + while (robot.getDirection() != dir) { + robot.turnLeft(); + } + } +} diff --git a/H04/src/main/java/h04/template/GameControllerTemplate.java b/H04/src/main/java/h04/template/GameControllerTemplate.java index f5686c9..f16da27 100644 --- a/H04/src/main/java/h04/template/GameControllerTemplate.java +++ b/H04/src/main/java/h04/template/GameControllerTemplate.java @@ -13,12 +13,9 @@ import h04.chesspieces.Pawn; import h04.chesspieces.Queen; import h04.chesspieces.Rook; import h04.chesspieces.Team; -//Wichtig für Implementation -//import h04.movement.MoveStrategy; -//Wichtig für Implementation -//import h04.movement.TeleportingMoveStrategy; -//Wichtig für Implementation -//import h04.movement.WalkingMoveStrategy; +import h04.movement.MoveStrategy; +import h04.movement.TeleportingMoveStrategy; +import h04.movement.WalkingMoveStrategy; import org.jetbrains.annotations.Nullable; import org.tudalgo.algoutils.student.io.PropertyUtils; @@ -45,13 +42,10 @@ public abstract class GameControllerTemplate { protected @Nullable ChessPiece selectedPiece; - //Wichtig für Implementation - /* protected MoveStrategy moveStrategy = PropertyUtils.getBooleanProperty( "h04.properties", "USE_TELEPORT_MOVE_STRATEGY" ) ? new TeleportingMoveStrategy() : new WalkingMoveStrategy(); - */ /** * Starts the game loop. @@ -62,8 +56,6 @@ public abstract class GameControllerTemplate { while (!gameOver) { final var point = inputHandler.getNextInput(nextToMove); - //Wichtig für Implementation - /* if (ChessUtils.getTeamAt(point) == nextToMove) { // select piece selectedPiece = ChessUtils.getPieceAt(point); @@ -107,7 +99,6 @@ public abstract class GameControllerTemplate { nextToMove = nextToMove.getOpponent(); selectedPiece = null; } - */ } } diff --git a/H05/src/main/java/h05/Airspace.java b/H05/src/main/java/h05/Airspace.java index d150797..aca891c 100644 --- a/H05/src/main/java/h05/Airspace.java +++ b/H05/src/main/java/h05/Airspace.java @@ -16,7 +16,7 @@ public class Airspace { } // TODO: H5.1.1 - Uncomment the following lines - /* private final Set flyingInAirspace = new HashSet<>(); + private final Set flyingInAirspace = new HashSet<>(); private Airspace(){ @@ -28,9 +28,27 @@ public class Airspace { void deregister(Flying flying){ flyingInAirspace.remove(flying); - } */ + } void scanAirspace() { // TODO: H5.5 + System.out.println("Scanning..."); + + if (flyingInAirspace.isEmpty()) { + System.out.println("Airspace is empty"); + return; + } + + for (var f : flyingInAirspace) { + if (f instanceof CarriesPassengers cp) { + System.out.printf("%s is flying in airspace (%d PAX).\n", f.getIdentifier(), cp.getPassengerCount()); + } else { + System.out.printf("%s is flying in airspace.\n", f.getIdentifier()); + } + } + } + + public Set getFlyingInAirspace() { + return flyingInAirspace; } } diff --git a/H05/src/main/java/h05/CargoPlane.java b/H05/src/main/java/h05/CargoPlane.java new file mode 100644 index 0000000..fdcad24 --- /dev/null +++ b/H05/src/main/java/h05/CargoPlane.java @@ -0,0 +1,30 @@ +package h05; + +public class CargoPlane extends Plane implements CarriesCargo { + + private final CargoStack containers = new CargoStack(); + + public CargoPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity) { + super(aircraftRegistration, baseWeight, fuelType, fuelCapacity); + } + + @Override + public void loadContainer(int cargoWeight) { + containers.push(cargoWeight); + } + + @Override + public boolean hasFreightLoaded() { + return !containers.empty(); + } + + @Override + public int unloadNextContainer() { + return containers.pop(); + } + + @Override + protected double mass() { + return getBaseWeight() + containers.getSum(); + } +} diff --git a/H05/src/main/java/h05/CarriesCargo.java b/H05/src/main/java/h05/CarriesCargo.java new file mode 100644 index 0000000..982e6eb --- /dev/null +++ b/H05/src/main/java/h05/CarriesCargo.java @@ -0,0 +1,10 @@ +package h05; + +public interface CarriesCargo { + + void loadContainer(int cargoWeight); + + boolean hasFreightLoaded(); + + int unloadNextContainer(); +} diff --git a/H05/src/main/java/h05/CarriesPassengers.java b/H05/src/main/java/h05/CarriesPassengers.java new file mode 100644 index 0000000..b873888 --- /dev/null +++ b/H05/src/main/java/h05/CarriesPassengers.java @@ -0,0 +1,10 @@ +package h05; + +public interface CarriesPassengers { + + void board(int passengers); + + void disembark(); + + int getPassengerCount(); +} diff --git a/H05/src/main/java/h05/CombinedPlane.java b/H05/src/main/java/h05/CombinedPlane.java new file mode 100644 index 0000000..42805de --- /dev/null +++ b/H05/src/main/java/h05/CombinedPlane.java @@ -0,0 +1,53 @@ +package h05; + +public class CombinedPlane extends Plane implements CarriesCargo, CarriesPassengers{ + + protected static final char AVERAGE_PEOPLE_WEIGHT = 100; + protected static final char AVERAGE_LUGGAGE_WEIGHT = 15; + + private final int crewCount; + + private int passengerCount = 0; + + public CombinedPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity, int crewCount) { + super(aircraftRegistration, baseWeight, fuelType, fuelCapacity); + this.crewCount = crewCount; + } + + @Override + protected double mass() { + return containers.getSum() + getBaseWeight() + passengerCount * AVERAGE_LUGGAGE_WEIGHT + passengerCount * AVERAGE_PEOPLE_WEIGHT + crewCount * AVERAGE_PEOPLE_WEIGHT; + } + + @Override + public void board(int passengers) { + passengerCount += passengers; + } + + @Override + public void disembark() { + passengerCount = 0; + } + + @Override + public int getPassengerCount() { + return passengerCount; + } + + private final CargoStack containers = new CargoStack(); + + @Override + public void loadContainer(int cargoWeight) { + containers.push(cargoWeight); + } + + @Override + public boolean hasFreightLoaded() { + return !containers.empty(); + } + + @Override + public int unloadNextContainer() { + return containers.pop(); + } +} diff --git a/H05/src/main/java/h05/Flying.java b/H05/src/main/java/h05/Flying.java new file mode 100644 index 0000000..a62dac5 --- /dev/null +++ b/H05/src/main/java/h05/Flying.java @@ -0,0 +1,6 @@ +package h05; + +public interface Flying { + + String getIdentifier(); +} diff --git a/H05/src/main/java/h05/FuelType.java b/H05/src/main/java/h05/FuelType.java new file mode 100644 index 0000000..2cac287 --- /dev/null +++ b/H05/src/main/java/h05/FuelType.java @@ -0,0 +1,18 @@ +package h05; + +public enum FuelType { + AvGas(0.99), + Biokerosin(1.02), + JetA(1.0), + JetB(1.2); + + private final double consumptionMultiplicator; + + FuelType(double consumptionMultiplicator) { + this.consumptionMultiplicator = consumptionMultiplicator; + } + + public double getConsumptionMultiplicator() { + return consumptionMultiplicator; + } +} diff --git a/H05/src/main/java/h05/Main.java b/H05/src/main/java/h05/Main.java index 68ebb41..de691b8 100644 --- a/H05/src/main/java/h05/Main.java +++ b/H05/src/main/java/h05/Main.java @@ -11,5 +11,50 @@ public class Main { */ public static void main(String[] args) { // TODO: H5.6 + Airspace.get().scanAirspace(); + + var longRunway = new Runway(4000); + + var shortRunway = new Runway(2000); + + var balloon = new WeatherBalloon(99); + balloon.start(); + + var tankA = new Tank(FuelType.JetA); + + var tankB = new Tank(FuelType.JetB); + + var tankerPlane = new TankerPlane("D-ABCD", 10000, FuelType.JetA, 1000); + tankerPlane.loadFuel(FuelType.AvGas, 100000); + tankerPlane.takeOff(); + + var passangerPlane = new PassengerPlane("GAG-67", 10000, FuelType.JetA, 1700, 5); + tankA.refuelPlane(passangerPlane); + passangerPlane.board(100); + passangerPlane.takeOff(); + + Airspace.get().scanAirspace(); + + var cargoPlane = new CargoPlane("D-AFFF", 8000, FuelType.JetB, 1500); + cargoPlane.loadContainer(1000); + tankB.refuelPlane(cargoPlane); + + var combinedPlane = new CombinedPlane("D-ABBB", 9000, FuelType.AvGas, 10700, 5); + tankerPlane.refuelPlane(combinedPlane); + combinedPlane.board(30); + combinedPlane.loadContainer(400); + combinedPlane.takeOff(); + combinedPlane.fly(3000); + + Airspace.get().scanAirspace(); + + shortRunway.land(combinedPlane); + longRunway.land(cargoPlane); + + Airspace.get().scanAirspace(); + + balloon.pop(); + + Airspace.get().scanAirspace(); } } diff --git a/H05/src/main/java/h05/PassengerPlane.java b/H05/src/main/java/h05/PassengerPlane.java new file mode 100644 index 0000000..3e40d0f --- /dev/null +++ b/H05/src/main/java/h05/PassengerPlane.java @@ -0,0 +1,36 @@ +package h05; + +public class PassengerPlane extends Plane implements CarriesPassengers { + + protected static final char AVERAGE_PEOPLE_WEIGHT = 100; + protected static final char AVERAGE_LUGGAGE_WEIGHT = 15; + + private final int crewCount; + + private int passengerCount = 0; + + public PassengerPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity, int crewCount) { + super(aircraftRegistration, baseWeight, fuelType, fuelCapacity); + this.crewCount = crewCount; + } + + @Override + protected double mass() { + return getBaseWeight() + passengerCount * AVERAGE_LUGGAGE_WEIGHT + passengerCount * AVERAGE_PEOPLE_WEIGHT + crewCount * AVERAGE_PEOPLE_WEIGHT; + } + + @Override + public void board(int passengers) { + passengerCount += passengers; + } + + @Override + public void disembark() { + passengerCount = 0; + } + + @Override + public int getPassengerCount() { + return passengerCount; + } +} diff --git a/H05/src/main/java/h05/Plane.java b/H05/src/main/java/h05/Plane.java new file mode 100644 index 0000000..8130526 --- /dev/null +++ b/H05/src/main/java/h05/Plane.java @@ -0,0 +1,80 @@ +package h05; + +public abstract class Plane implements Flying { + + private static final double CONSUMPTION_PER_KM_KG = 1.1494e-4; + + private final String aircraftRegistration; + + private final int baseWeight; + + private final FuelType fuelType; + + private final double fuelCapacity; + + private double currentFuelLevel; + + public Plane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity) { + this.aircraftRegistration = aircraftRegistration; + this.baseWeight = baseWeight; + this.fuelType = fuelType; + this.fuelCapacity = fuelCapacity; + this.currentFuelLevel = 0; + } + + @Override + public String getIdentifier() { + return aircraftRegistration; + } + + public double getCurrentFuelLevel() { + return currentFuelLevel; + } + + public double getFuelCapacity() { + return fuelCapacity; + } + + public FuelType getFuelType() { + return fuelType; + } + + public int getBaseWeight() { + return baseWeight; + } + + public void refuel(double amount) { + if (currentFuelLevel + amount > fuelCapacity) { + System.out.printf("The Tank of Plane %s has overflowed!\n", aircraftRegistration); + return; + } + + currentFuelLevel += amount; + } + + protected abstract double mass(); + + protected double getFuelConsumptionPerKilometer() { + return CONSUMPTION_PER_KM_KG * fuelType.getConsumptionMultiplicator() * mass(); + } + + public void fly(double distance) { + var fuelNeeded = getFuelConsumptionPerKilometer() * distance; + + if (currentFuelLevel < fuelNeeded) { + System.out.printf("Plane %s does not have enough fuel to fly %f km.", aircraftRegistration, distance / 100000); + return; + } + + currentFuelLevel -= fuelNeeded; + System.out.printf("Plane %s flew %s km and has %s liters of fuel left.", aircraftRegistration, distance, currentFuelLevel); + } + + public void takeOff() { + Airspace.get().register(this); + } + + public void land() { + Airspace.get().deregister(this); + } +} diff --git a/H05/src/main/java/h05/Refuelling.java b/H05/src/main/java/h05/Refuelling.java new file mode 100644 index 0000000..4ffcb5f --- /dev/null +++ b/H05/src/main/java/h05/Refuelling.java @@ -0,0 +1,6 @@ +package h05; + +public interface Refuelling { + + void refuelPlane(Plane plane); +} diff --git a/H05/src/main/java/h05/Runway.java b/H05/src/main/java/h05/Runway.java new file mode 100644 index 0000000..2c4c49e --- /dev/null +++ b/H05/src/main/java/h05/Runway.java @@ -0,0 +1,31 @@ +package h05; + +public class Runway { + + private final int runwayLength; + + public Runway(int runwayLength) { + this.runwayLength = runwayLength; + } + + public int getRunwayLength() { + return runwayLength; + } + + public static double calculateLandingDistance(double mass) { + return mass / 40; + } + + public boolean canLand(Plane plane) { + return runwayLength >= calculateLandingDistance(plane.mass()); + } + + public void land(Plane plane) { + if (canLand(plane)) { + plane.land(); + System.out.printf("Plane %s has landed successfully.\n", plane.getIdentifier()); + } else { + System.out.printf("Plane %s could not land. The runway is too short.\n", plane.getIdentifier()); + } + } +} diff --git a/H05/src/main/java/h05/Tank.java b/H05/src/main/java/h05/Tank.java new file mode 100644 index 0000000..e521fae --- /dev/null +++ b/H05/src/main/java/h05/Tank.java @@ -0,0 +1,22 @@ +package h05; + +public class Tank implements Refuelling { + + private final FuelType fuelType; + + public Tank(FuelType fuelType) { + this.fuelType = fuelType; + } + + @Override + public void refuelPlane(Plane plane) { + if (plane.getFuelType() != fuelType) { + System.out.println("Hat nicht geklappt >:("); + return; + } + + plane.refuel(plane.getFuelCapacity() - plane.getCurrentFuelLevel()); + } + + +} diff --git a/H05/src/main/java/h05/TankerPlane.java b/H05/src/main/java/h05/TankerPlane.java new file mode 100644 index 0000000..f045897 --- /dev/null +++ b/H05/src/main/java/h05/TankerPlane.java @@ -0,0 +1,35 @@ +package h05; + +import java.util.stream.DoubleStream; + +public class TankerPlane extends Plane implements Refuelling { + + private final double[] availableAmount = new double[FuelType.values().length]; + + public TankerPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity) { + super(aircraftRegistration, baseWeight, fuelType, fuelCapacity); + } + + @Override + protected double mass() { + return getBaseWeight() + DoubleStream.of(availableAmount).sum(); + } + + @Override + public void refuelPlane(Plane plane) { + var diff = plane.getFuelCapacity() - plane.getCurrentFuelLevel(); + var avail = availableAmount[plane.getFuelType().ordinal()]; + + if (diff > avail) { + System.out.println("auawuduiwahduihdauwihdw"); + return; + } + + plane.refuel(diff); + availableAmount[plane.getFuelType().ordinal()] -= diff; + } + + public void loadFuel(FuelType type, double amount) { + availableAmount[type.ordinal()] = amount; + } +} diff --git a/H05/src/main/java/h05/WeatherBalloon.java b/H05/src/main/java/h05/WeatherBalloon.java new file mode 100644 index 0000000..5c6fe6d --- /dev/null +++ b/H05/src/main/java/h05/WeatherBalloon.java @@ -0,0 +1,25 @@ +package h05; + +import kotlin.Pair; + +public class WeatherBalloon implements Flying { + + private final int balloonNumber; + + public WeatherBalloon(int balloonNumber) { + this.balloonNumber = balloonNumber; + } + + @Override + public String getIdentifier() { + return "WeatherBalloon " + balloonNumber; + } + + public void start() { + Airspace.get().register(this); + } + + public void pop() { + Airspace.get().deregister(this); + } +} diff --git a/H07/src/main/java/h07/Main.java b/H07/src/main/java/h07/Main.java deleted file mode 100644 index 4a57760..0000000 --- a/H07/src/main/java/h07/Main.java +++ /dev/null @@ -1,66 +0,0 @@ -package h07; - -import org.tudalgo.algoutils.student.annotation.DoNotTouch; -import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; - -import h07.peano.NaturalNumber; -import h07.peano.Successor; -import h07.peano.Zero; - -import static org.tudalgo.algoutils.student.Student.crash; - -/** - * Main entry point in executing the program. - */ -public class Main { - /** - * Main entry point in executing the program. - * - * @param args program arguments, currently ignored - */ - public static void main(String[] args) { - testHeader("Multiplication Table"); - numberExpressionMultiplicationTableTests(); - - testHeader("Peano Number Expressions"); - peanoNumberExpressionTests(); - - testHeader("Filter, Fold, Map"); - filterFoldMapTests(); - } - - @DoNotTouch - private static void testHeader(String testName) { - System.out.println("-----------------------------------"); - System.out.println("Running test: " + testName); - System.out.println("-----------------------------------"); - } - - @DoNotTouch - private static void numberExpressionMultiplicationTableTests() { - // TODO: H2.2 - uncomment to test -// int lowerBound = 1; -// int upperBound = 10; -// NumberExpression[] multiplicationTable = NumberExpressionFactory.multiplicationTable(lowerBound, upperBound); -// -// for (int i = lowerBound; i <= upperBound; i++) { -// for (int j = lowerBound; j <= upperBound; j++) { -// System.out.printf("| %4s ", multiplicationTable[(i - lowerBound) * (upperBound - lowerBound + 1) + (j - lowerBound)].evaluate()); -// } -// System.out.println("|"); -// } - } - - private static final NaturalNumber THREE = new Successor(new Successor(new Successor(new Zero()))); - private static final NaturalNumber SEVEN = new Successor(new Successor(new Successor(new Successor(new Successor(new Successor(new Successor(new Zero()))))))); - - @StudentImplementationRequired - private static void peanoNumberExpressionTests() { - crash(); // TODO: H3.3 - remove if implemented - } - - @StudentImplementationRequired - private static void filterFoldMapTests() { - crash(); // TODO: H4.6 - remove if implemented - } -} diff --git a/H07/src/main/java/h07/NumberExpressionFactory.java b/H07/src/main/java/h07/NumberExpressionFactory.java deleted file mode 100644 index f2bb270..0000000 --- a/H07/src/main/java/h07/NumberExpressionFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -package h07; - -import java.util.function.IntPredicate; - -import org.tudalgo.algoutils.student.annotation.DoNotTouch; -import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; - -import static org.tudalgo.algoutils.student.Student.crash; - -/** - * A factory class for creating number expressions. - */ -public class NumberExpressionFactory { - /** - * Calculates the product of all possible pairs of numbers in the given array. - * - * @param numbers the array of number expressions to calculate the multiplication table - * @return An array of number expressions representing the result of the - * multiplication table of the given numbers. - */ -// @StudentImplementationRequired -// public static NumberExpression[] multiplicationTable(NumberExpression[] numbers) { -// return crash(); // TODO: H2.1 - remove if implemented -// } - - - // TODO: H2.2 - uncomment for testing - /** - * Calculates the product of all possible pairs of numbers in the given range. - * - * @param lowerBound the lower bound of the multiplication table, inclusive - * @param upperBound the upper bound of the multiplication table, inclusive - * @return An array of number expressions representing the result of the - * multiplication table of the numbers from lowerBound to upperBound. - */ -// @DoNotTouch -// public static NumberExpression[] multiplicationTable(int lowerBound, int upperBound) { -// int numberOfNumbers = upperBound - lowerBound + 1; -// NumberExpression[] baseNumbers = new NumberExpression[numberOfNumbers]; -// -// for (int i = lowerBound; i <= upperBound; i++) { -// // Copy to local variable to make it effectively final, so it can be used in -// // lambda -// int finalI = i; -// baseNumbers[i - lowerBound] = () -> finalI; -// } -// -// return multiplicationTable(baseNumbers); -// } - - /** - * Filters the given array of number expressions based on the given predicate. - * The returned array should contain only the number expressions that satisfy - * the predicate in the same order as they appear in the input array. - * This means there should be no null values in the returned array. - * - * @param numbers the array of number expressions to filter - * @param predicate the predicate to filter the number expressions - * @return An array of number expressions that satisfy the predicate. - */ -// @StudentImplementationRequired -// public static NumberExpression[] filter(NumberExpression[] numbers, IntPredicate predicate) { -// return crash(); // TODO: H4.4 - remove if implemented -// } -} diff --git a/H07/src/main/java/h07/peano/NaturalNumber.java b/H07/src/main/java/h07/peano/NaturalNumber.java deleted file mode 100644 index 2575c74..0000000 --- a/H07/src/main/java/h07/peano/NaturalNumber.java +++ /dev/null @@ -1,17 +0,0 @@ -package h07.peano; - -import org.tudalgo.algoutils.student.annotation.DoNotTouch; - -/** - * Represents a natural number. - */ -@DoNotTouch -public abstract class NaturalNumber { - /** - * Returns the string representation of the natural number. - * - * @return the string representation of the natural number - */ - @Override - public abstract String toString(); -} diff --git a/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java b/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java deleted file mode 100644 index 753da6f..0000000 --- a/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -package h07.peano; - - -import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; - -import static org.tudalgo.algoutils.student.Student.crash; - -/** - * Represents a factory for Peano number expressions. - */ -public class PeanoNumberExpressionFactory { - /** - * Converts an array of number expressions to an array of Peano number expressions. - * - * @param numberExpressions the number expressions to convert - * @return the converted Peano number expressions - */ -// @StudentImplementationRequired -// public static PeanoNumberExpression[] fromNumberExpressions(NumberExpression[] numberExpressions) { -// return crash(); // TODO: H4.3 - remove if implemented -// } - - /** - * Folds an array of Peano number expressions into a single Peano number expression. - * - * @param peanoNumberExpressions the Peano number expressions to fold - * @param initial the initial Peano number expression - * @param operation the operation to apply - * @return the folded Peano number expression - */ -// @StudentImplementationRequired -// public static PeanoNumberExpression fold(PeanoNumberExpression[] peanoNumberExpressions, PeanoNumberExpression initial, PeanoArithmeticExpression operation) { -// return crash(); // TODO: H4.5 - remove if implemented -// } -} diff --git a/H07/src/main/java/h07/peano/Successor.java b/H07/src/main/java/h07/peano/Successor.java deleted file mode 100644 index 261f24f..0000000 --- a/H07/src/main/java/h07/peano/Successor.java +++ /dev/null @@ -1,20 +0,0 @@ -package h07.peano; - -import org.tudalgo.algoutils.student.annotation.DoNotTouch; - -/** - * Represents a successor of a natural number in Peano arithmetic. - */ -@DoNotTouch -public class Successor extends NaturalNumber { - public final NaturalNumber predecessor; - - public Successor(NaturalNumber predecessor) { - this.predecessor = predecessor; - } - - @Override - public String toString() { - return "S(" + predecessor.toString() + ")"; - } -} diff --git a/H07/src/main/java/h07/peano/Zero.java b/H07/src/main/java/h07/peano/Zero.java deleted file mode 100644 index 4aa12d9..0000000 --- a/H07/src/main/java/h07/peano/Zero.java +++ /dev/null @@ -1,14 +0,0 @@ -package h07.peano; - -import org.tudalgo.algoutils.student.annotation.DoNotTouch; - -/** - * Represents the number zero in Peano arithmetic. - */ -@DoNotTouch -public class Zero extends NaturalNumber { - @Override - public String toString() { - return "Z"; - } -} diff --git a/H07/.editorconfig b/H08/.editorconfig similarity index 100% rename from H07/.editorconfig rename to H08/.editorconfig diff --git a/H07/.gitignore b/H08/.gitignore similarity index 100% rename from H07/.gitignore rename to H08/.gitignore diff --git a/H07/README.md b/H08/README.md similarity index 85% rename from H07/README.md rename to H08/README.md index fc2f4da..d825e04 100644 --- a/H07/README.md +++ b/H08/README.md @@ -1,4 +1,4 @@ -# Vorlage zu Hausübung 07 +# Vorlage zu Hausübung 08 Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem [Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/H07/build.gradle.kts b/H08/build.gradle.kts similarity index 91% rename from H07/build.gradle.kts rename to H08/build.gradle.kts index d22a930..a67dd19 100644 --- a/H07/build.gradle.kts +++ b/H08/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } exercise { - assignmentId.set("h07") + assignmentId.set("h08") } submission { @@ -31,3 +31,7 @@ tasks { } } } + +application { + applicationDefaultJvmArgs += "-ea" +} diff --git a/H07/gradle/libs.versions.toml b/H08/gradle/libs.versions.toml similarity index 100% rename from H07/gradle/libs.versions.toml rename to H08/gradle/libs.versions.toml diff --git a/H07/gradle/wrapper/gradle-wrapper.jar b/H08/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from H07/gradle/wrapper/gradle-wrapper.jar rename to H08/gradle/wrapper/gradle-wrapper.jar diff --git a/H07/gradle/wrapper/gradle-wrapper.properties b/H08/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from H07/gradle/wrapper/gradle-wrapper.properties rename to H08/gradle/wrapper/gradle-wrapper.properties diff --git a/H07/gradlew b/H08/gradlew similarity index 100% rename from H07/gradlew rename to H08/gradlew diff --git a/H07/gradlew.bat b/H08/gradlew.bat similarity index 100% rename from H07/gradlew.bat rename to H08/gradlew.bat diff --git a/H07/settings.gradle.kts b/H08/settings.gradle.kts similarity index 89% rename from H07/settings.gradle.kts rename to H08/settings.gradle.kts index 68797bc..443bb4c 100644 --- a/H07/settings.gradle.kts +++ b/H08/settings.gradle.kts @@ -8,4 +8,4 @@ dependencyResolutionManagement { } } -rootProject.name = "H07-Student" +rootProject.name = "H08-Student" diff --git a/H08/src/main/java/h08/Airport.java b/H08/src/main/java/h08/Airport.java new file mode 100644 index 0000000..e182039 --- /dev/null +++ b/H08/src/main/java/h08/Airport.java @@ -0,0 +1,114 @@ +package h08; + + +import java.util.Arrays; + +/** + * Represents an airport. An airport manages departing and arriving flights, allowing for their addition, removal, and retrieval based on the airport code. + */ +public class Airport { + + /** + * The code of the airport. + */ + private String airportCode; + + /** + * The departing flights of the airport. + */ + private Flight[] departingFlights; + + /** + * The arriving flights to the airport. + */ + private Flight[] arrivingFlights; + + /** + * The number of departing flights of the airport. + */ + private int departingSize; + + /** + * The number of arriving flights to the airport. + */ + private int arrivingSize; + + /** + * Constructs a new airport with the specified airport code and initial capacity. + * + * @param airportCode the code of the airport + * @param initialCapacity the initial capacity of the airport + */ + public Airport(String airportCode, int initialCapacity) { + this.airportCode = airportCode; + this.departingFlights = new Flight[initialCapacity]; + this.arrivingFlights = new Flight[initialCapacity]; + this.departingSize = 0; + this.arrivingSize = 0; + } + + /** + * Adds a flight. + * + * @param flight the flight to add + * @param isDeparting if true, adds to departing flights, otherwise to arriving flights + * @throws IllegalArgumentException if the flight's airport code doesn't match the airport's code + */ + public void addFlight(Flight flight, boolean isDeparting) { + //TODO H8.4.1 + org.tudalgo.algoutils.student.Student.crash("H8.4.1 - Remove if implemented"); + } + + /** + * Removes a flight by flight number. + * + * @param flightNumber the flight number + * @param isDeparting if true, removes from departing flights, otherwise from arriving flights + * @throws FlightNotFoundException if the flight is not found + */ + public void removeFlight(String flightNumber, boolean isDeparting) { + //TODO H8.4.2 + org.tudalgo.algoutils.student.Student.crash("H8.4.2 - Remove if implemented"); + } + + /** + * Returns a flight by flight number. + * + * @param flightNumber the flight number + * @param isDeparting if true, searches in departing flights, otherwise in arriving flights + * @return the flight with the specified flight number + * @throws FlightNotFoundException if the flight is not found + */ + public Flight getFlight(String flightNumber, boolean isDeparting) { + //TODO H8.4.3 + return org.tudalgo.algoutils.student.Student.crash("H8.4.3 - Remove if implemented"); + } + + + /** + * Returns the departing flights of the airport. + * + * @return the departing flights of the airport + */ + public Flight[] getAllDepartingFlights() { + return Arrays.copyOf(departingFlights, departingSize); + } + + /** + * Returns the arriving flights to the airport. + * + * @return the arriving flights to the airport + */ + public Flight[] getAllArrivingFlights() { + return Arrays.copyOf(arrivingFlights, arrivingSize); + } + + /** + * Returns the airport code. + * + * @return the airport code + */ + public String getAirportCode() { + return airportCode; + } +} diff --git a/H08/src/main/java/h08/Booking.java b/H08/src/main/java/h08/Booking.java new file mode 100644 index 0000000..8838392 --- /dev/null +++ b/H08/src/main/java/h08/Booking.java @@ -0,0 +1,97 @@ +package h08; + +/** + * Represents a flight booking. A booking allows the reservation of a flight as long as managing its identification and its relevant information. + */ +public class Booking { + + /** + * The booking ID of a booking. + */ + private String bookingId; + + /** + * The flight number of a booking. + */ + private String flightNumber; + + /** + * The passenger ID of a booking. + */ + private String passengerId; + + /** + * The cancellations status of a booking. + */ + private boolean isCancelled; + + /** + * Constructs a new booking with the specified booking ID, flight number and passenger ID. + * + * @param bookingId the booking ID of the booking + * @param flightNumber the flight number of the booking + * @param passengerId the passenger ID of the booking + */ + public Booking(String bookingId, String flightNumber, String passengerId) { + this.bookingId = bookingId; + this.flightNumber = flightNumber; + this.passengerId = passengerId; + this.isCancelled = false; + } + + /** + * Returns the booking ID of the booking. + * + * @return the booking ID of the booking + */ + public String getBookingId() { + return bookingId; + } + + /** + * Returns the flight number of the booking. + * + * @return the flight number of the booking + */ + public String getFlightNumber() { + return flightNumber; + } + + /** + * Returns the passenger ID of the booking. + * + * @return the passenger ID of the booking + */ + public String getPassengerId() { + return passengerId; + } + + /** + * Returns the cancellation status of the booking. + * + * @return the cancellation status of the booking + */ + public boolean isCancelled() { + return isCancelled; + } + + /** + * Cancels the booking. + * + * @throws BookingAlreadyCancelledException if the booking is already cancelled + */ + public void cancelBooking() { + //TODO H8.4.4 + org.tudalgo.algoutils.student.Student.crash("H8.4.4 - Remove if implemented"); + } + + /** + * Returns the booking details. + * + * @return the booking details + */ + public String viewBooking() { + return String.format("Booking ID: %s, Flight Number: %s, Passenger ID: %s, Is Cancelled: %b", + bookingId, flightNumber, passengerId, isCancelled); + } +} diff --git a/H08/src/main/java/h08/BookingManagement.java b/H08/src/main/java/h08/BookingManagement.java new file mode 100644 index 0000000..fed0b6e --- /dev/null +++ b/H08/src/main/java/h08/BookingManagement.java @@ -0,0 +1,93 @@ +package h08; + +/** + * Represents a booking management. A booking management oversees booking operations, ensuring validity and handling duplicates. + */ +public class BookingManagement { + + /** + * The bookings to be managed. + */ + private Booking[] bookings; + + /** + * The current number of bookings. + */ + private int size; + + /** + * The flight management for the bookings. + */ + private FlightManagement flightManagement; + + /** + * Constructs a new booking management with the specified initial capacity and flight management. + * + * @param initialCapacity the initial number of bookings that can be managed + * @param flightManagement the flight management for the bookings + */ + public BookingManagement(int initialCapacity, FlightManagement flightManagement) { + this.bookings = new Booking[initialCapacity]; + this.size = 0; + this.flightManagement = flightManagement; + } + + /** + * Creates a booking. + * + * @param bookingId the booking ID of the booking + * @param flightNumber the flight number of the booking + * @param passengerId the passenger ID of the booking + */ + public void createBooking(String bookingId, String flightNumber, String passengerId) { + //TODO H8.5.5 + org.tudalgo.algoutils.student.Student.crash("H8.5.5 - Remove if implemented"); + } + + /** + * Validates the booking details and checks for duplicates. + * + * @param bookingId the booking ID of the booking + * @param flightNumber the flight number of the booking + * @param passengerId the passenger ID of the booking + * @throws InvalidBookingException if the booking details are invalid + * @throws DuplicateBookingException if the booking ID is already in use + */ + private void validateAndCheckBooking(String bookingId, String flightNumber, String passengerId){ + //TODO H8.5.2 + org.tudalgo.algoutils.student.Student.crash("H8.5.2 - Remove if implemented"); + } + + /** + * Searches for a booking by booking ID. + * + * @param bookingId the booking ID of the booking + * @return the booking with the specified booking ID + * @throws BookingNotFoundException if the booking ist not found + */ + private Booking searchBooking(String bookingId){ + //TODO H8.5.3 + return org.tudalgo.algoutils.student.Student.crash("H8.5.3 - Remove if implemented"); + } + + /** + * Returns a booking by booking ID. + * + * @param bookingId the booking ID of the booking + * @return the booking with the specified booking ID + */ + public Booking getBooking(String bookingId) { + //TODO H8.5.3 + return org.tudalgo.algoutils.student.Student.crash("H8.5.3 - Remove if implemented"); + } + + /** + * Cancels a booking by booking ID. + * + * @param bookingId the booking ID of the booking + */ + public void cancelBooking(String bookingId) { + //TODO H8.5.4 + org.tudalgo.algoutils.student.Student.crash("H8.5.4 - Remove if implemented"); + } +} diff --git a/H08/src/main/java/h08/Flight.java b/H08/src/main/java/h08/Flight.java new file mode 100644 index 0000000..18e033e --- /dev/null +++ b/H08/src/main/java/h08/Flight.java @@ -0,0 +1,146 @@ +package h08; + +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.time.LocalDateTime; + +/** + * Represents a flight. A flight offers information such as the flight details and seat management. + */ +public class Flight { + + /** + * The flight number of the flight. + */ + private String flightNumber; + + /** + * The departure airport of the flight. + */ + private String departure; + + /** + * The destination airport of the flight. + */ + private String destination; + + /** + * The departure time of the flight. + */ + private LocalDateTime departureTime; + + /** + * The initial number of seats of the flight. + */ + private final int initialSeats; + + /** + * The number of available seats. + */ + private int availableSeats; + + /** + * Constructs a new flight with the specified flight number, departure airport, destination airport, departure time and initial number of seats. + * + * @param flightNumber the flight number of the flight + * @param departure the departure airport of the flight + * @param destination the destination airport of the flight + * @param departureTime the departure time of the flight + * @param initialSeats the initial number of seats of the flight + */ + public Flight(String flightNumber, String departure, String destination, LocalDateTime departureTime, int initialSeats) { + //TODO H8.2.1 + this.flightNumber = flightNumber; + this.departure = departure; + this.destination = destination; + this.departureTime = departureTime; + this.initialSeats = initialSeats; + this.availableSeats = initialSeats; + + } + + /** + * Validates the flight number. + * + * @param flightNumber the flight number of the flight + */ + @StudentImplementationRequired("H8.2.1") + public void validateFlightNumber(String flightNumber) { + //TODO H8.2.1 + org.tudalgo.algoutils.student.Student.crash("H8.2.1 - Remove if implemented"); + } + + /** + * Returns the flight number of the flight. + * + * @return the flight number of the flight + */ + public String getFlightNumber() { + return flightNumber; + } + + /** + * Returns the departure airport of the flight. + * + * @return the departure airport of the flight + */ + public String getDeparture() { + return departure; + } + + /** + * Returns the destination airport of the flight. + * + * @return the destination airport of the flight + */ + public String getDestination() { + return destination; + } + + /** + * Returns the departure time of the flight. + * + * @return the departure time of the flight + */ + public String getDepartureTime() { + return departureTime.toString(); + } + + /** + * Returns the number of available seats of the flight. + * + * @return the number of available seats of the flight + */ + public int getAvailableSeats() { + return availableSeats; + } + + @StudentImplementationRequired("H8.2.2") + public void bookSeat() { + //TODO H8.2.2 + org.tudalgo.algoutils.student.Student.crash("H8.2.2 - Remove if implemented"); + } + + public void cancelSeat() { + if (availableSeats < initialSeats) { + availableSeats++; + } + } + + /** + * Returns a string representation of the flight. + * + * @return a string representation of the flight + */ + @Override + public String toString() { + return "Flight{" + + "flightNumber='" + flightNumber + '\'' + + ", departure='" + departure + '\'' + + ", destination='" + destination + '\'' + + ", departureTime=" + departureTime + + ", initialSeats=" + initialSeats + + ", availableSeats=" + availableSeats + + '}'; + } +} diff --git a/H08/src/main/java/h08/FlightManagement.java b/H08/src/main/java/h08/FlightManagement.java new file mode 100644 index 0000000..e3f6e3e --- /dev/null +++ b/H08/src/main/java/h08/FlightManagement.java @@ -0,0 +1,106 @@ +package h08; + +import java.util.Arrays; + +/** + * Represents a flight management. A flight management oversees the management of flights and airports. + */ +public class FlightManagement { + + /** + * The airports whose flights are managed. + */ + private Airport[] airports; + + /** + * The current number of airports whose flights are managed. + */ + private int size; + + /** + * Constructs a new flight management with the specified initial capacity. + * + * @param initialCapacity the initial capacity + */ + public FlightManagement(int initialCapacity) { + this.airports = new Airport[initialCapacity]; + this.size = 0; + } + + /** + * Adds an airport to the flight management. + * + * @param airport the airport to be added + */ + public void addAirport(Airport airport) { + if (size >= airports.length) { + airports = Arrays.copyOf(airports, airports.length * 2); + } + airports[size++] = airport; + } + + /** + * Manages the addition or removal of a flight for a specific airport. + * + * @param airportCode the airport code where the flight should be managed + * @param flight the flight to be added or removed + * @param isAddOperation if true, the flight will be added; if false, the flight will be removed + */ + public void manageFlight(String airportCode, Flight flight, boolean isAddOperation) { + //TODO H8.5.2 + org.tudalgo.algoutils.student.Student.crash("H8.5.2 - Remove if implemented"); + } + + /** + * Returns a flight from a specific airport. + * + * @param airportCode the airport code from which the flight should be returned + * @param flightNumber the flight number of the flight + * @return a flight from a specific airport + */ + public Flight getFlight(String airportCode, String flightNumber){ + //TODO H8.5.1 + return org.tudalgo.algoutils.student.Student.crash("H8.5.1 - Remove if implemented"); + } + + /** + * Returns a flight with a specified flight number. + * + * @param flightNumber the flight number of the flight + * @return a flight with a specified flight number + */ + public Flight getFlight(String flightNumber){ + for (int i = 0; i < size; i++) { + Flight flight = searchFlight(airports[i], flightNumber); + if (flight != null) { + return flight; + } + } + System.out.println("Error retrieving flight: Flight not found: " + flightNumber); + return null; + } + + /** + * Searches for an airport by airport code. + * + * @param airportCode the airport code + * @return an airport by airport code + * @throws Exception if the airport ist not found + */ + private Airport searchAirport(String airportCode) { + //TODO H8.5.1 + return org.tudalgo.algoutils.student.Student.crash("H8.5.1 - Remove if implemented"); + } + + /** + * Searches for a flight in departing or arriving flights. + * + * @param airport the airport in which the flight should be searched + * @param flightNumber the flight number of the flight + * @return a flight in departing or arriving flights + */ + private Flight searchFlight(Airport airport, String flightNumber) { + //TODO H8.5.1 + return org.tudalgo.algoutils.student.Student.crash("H8.5.1 - Remove if implemented"); + } +} diff --git a/H08/src/main/java/h08/Main.java b/H08/src/main/java/h08/Main.java new file mode 100644 index 0000000..1640f36 --- /dev/null +++ b/H08/src/main/java/h08/Main.java @@ -0,0 +1,15 @@ +package h08; + +/** + * Main entry point in executing the program. + */ +public class Main { + /** + * Main entry point in executing the program. + * + * @param args program arguments, currently ignored + */ + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/H08/src/main/java/h08/Passenger.java b/H08/src/main/java/h08/Passenger.java new file mode 100644 index 0000000..fb91ece --- /dev/null +++ b/H08/src/main/java/h08/Passenger.java @@ -0,0 +1,111 @@ +package h08; + +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.time.LocalDate; + +/** + * Represents a passenger. A Passenger represents an individual with personal details and a unique identifier. + */ +public class Passenger { + + /** + * The ID of the passenger. + */ + private String passengerID; + + /** + * The first name of the passenger. + */ + private String firstName; + + /** + * The last name of the passenger. + */ + private String lastName; + + /** + * The date of birth of the passenger. + */ + private LocalDate dateOfBirth; + + /** + * Constructs a new passenger with the specified first name, last name and date of birth. + * + * @param firstName the first name of the passenger + * @param lastName the last name of the passenger + * @param dateOfBirth the date of birth of the passenger + */ + public Passenger(String firstName, String lastName, LocalDate dateOfBirth) { + this.firstName = firstName; + this.lastName = lastName; + this.dateOfBirth = dateOfBirth; + this.passengerID = generatePassengerID(firstName, lastName, dateOfBirth); + + } + + /** + * Returns the generated ID of the passenger. + * + * @param firstName the first name of the passenger + * @param lastName the last name of the passenger + * @param dateOfBirth the date of birth of the passenger + * @return the generated ID of the passenger + */ + @StudentImplementationRequired("H8.1") + private String generatePassengerID(String firstName, String lastName, LocalDate dateOfBirth) { + //TODO H8.1 + return org.tudalgo.algoutils.student.Student.crash("H8.1 - Remove if implemented"); + } + + /** + * Returns the ID of the passenger. + * + * @return the ID of the passenger + */ + public String getPassengerID() { + return passengerID; + } + + /** + * Returns the first name of the passenger. + * + * @return the first name of the passenger + */ + public String getFirstName() { + return firstName; + } + + /** + * Returns the last name of the passenger. + * + * @return the last name of the passenger + */ + public String getLastName() { + return lastName; + } + + /** + * Returns the date of birth of the passenger. + * + * @return the date of birth of the passenger + */ + public LocalDate getDateOfBirth() { + return dateOfBirth; + } + + /** + * Returns a string representation of the passenger. + * + * @return a string representation of the passenger + */ + @Override + public String toString() { + return "Passenger{" + + "passengerID='" + passengerID + '\'' + + ", firstName='" + firstName + '\'' + + ", lastName='" + lastName + '\'' + + ", dateOfBirth=" + dateOfBirth + + '}'; + } +} diff --git a/H07/src/test/java/h07/ExampleJUnitTest.java b/H08/src/test/java/h08/ExampleJUnitTest.java similarity index 94% rename from H07/src/test/java/h07/ExampleJUnitTest.java rename to H08/src/test/java/h08/ExampleJUnitTest.java index 0dd0ee9..92ae865 100644 --- a/H07/src/test/java/h07/ExampleJUnitTest.java +++ b/H08/src/test/java/h08/ExampleJUnitTest.java @@ -1,4 +1,4 @@ -package h07; +package h08; import org.junit.jupiter.api.Test; diff --git a/solution/H07/.editorconfig b/H09/.editorconfig similarity index 100% rename from solution/H07/.editorconfig rename to H09/.editorconfig diff --git a/H09/.gitignore b/H09/.gitignore new file mode 100644 index 0000000..7413272 --- /dev/null +++ b/H09/.gitignore @@ -0,0 +1,88 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +screenshots + +jagr.conf diff --git a/solution/H07/README.md b/H09/README.md similarity index 82% rename from solution/H07/README.md rename to H09/README.md index 77c343b..a690931 100644 --- a/solution/H07/README.md +++ b/H09/README.md @@ -1,4 +1,4 @@ -# Musterlösung zu Hausübung 07 +# Vorlage zu Hausübung 09 Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem [Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/H09/build.gradle.kts b/H09/build.gradle.kts new file mode 100644 index 0000000..7ed2fe4 --- /dev/null +++ b/H09/build.gradle.kts @@ -0,0 +1,33 @@ +import org.sourcegrade.jagr.gradle.task.grader.GraderRunTask + +plugins { + alias(libs.plugins.algomate) +} + +exercise { + assignmentId.set("h09") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "" + firstName = "" + lastName = "" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h09.H09_RubricProviderPublic") + } + } +} diff --git a/H09/gradle/libs.versions.toml b/H09/gradle/libs.versions.toml new file mode 100644 index 0000000..46d58d4 --- /dev/null +++ b/H09/gradle/libs.versions.toml @@ -0,0 +1,2 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } diff --git a/H09/gradle/wrapper/gradle-wrapper.jar b/H09/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/H09/gradlew.bat b/H09/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/H09/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/H09/settings.gradle.kts b/H09/settings.gradle.kts new file mode 100644 index 0000000..f6083ad --- /dev/null +++ b/H09/settings.gradle.kts @@ -0,0 +1,11 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + maven("https://jitpack.io") + mavenCentral() + } +} + +rootProject.name = "H09-Student" diff --git a/H09/src/graderPublic/java/h09/EnclosureTestPublic.java b/H09/src/graderPublic/java/h09/EnclosureTestPublic.java new file mode 100644 index 0000000..5bb6926 --- /dev/null +++ b/H09/src/graderPublic/java/h09/EnclosureTestPublic.java @@ -0,0 +1,149 @@ +package h09; + +import h09.abilities.Swims; +import h09.animals.Animal; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import static h09.H09_TestUtils.assertDefinedParameters; +import static h09.H09_TestUtils.assertParameters; +import static h09.H09_TestUtils.assertReturnParameter; +import static h09.H09_TestUtils.assertType; +import static h09.H09_TestUtils.getDefinedTypes; +import static h09.H09_TestUtils.match; +import static h09.H09_TestUtils.matchNested; +import static h09.H09_TestUtils.matchUpperBounds; +import static h09.H09_TestUtils.matchWildcard; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertNotNull; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.emptyContext; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.fail; +import static org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers.identical; + +@TestForSubmission +public class EnclosureTestPublic { + + BasicTypeLink enclosureLink; + Method getStack; + Method forEach; + Method filterObj; + Method filterFunc; + Method eatAndSink; + Field swimsAtLowElevation; + Field feedAndSleep; + + @BeforeEach + @SuppressWarnings("unchecked") + public void setUp() { + enclosureLink = BasicTypeLink.of(Enclosure.class); + + getStack = enclosureLink.getMethod(identical("getStack")).reflection(); + forEach = enclosureLink.getMethod(identical("forEach")).reflection(); + filterObj = enclosureLink.getMethod(identical("filterObj")).reflection(); + filterFunc = enclosureLink.getMethod(identical("filterFunc")).reflection(); + eatAndSink = enclosureLink.getMethod(identical("EAT_AND_SINK")).reflection(); + + swimsAtLowElevation = enclosureLink.getField(identical("SWIMS_AT_LOW_ELEVATION")).reflection(); + feedAndSleep = enclosureLink.getField(identical("FEED_AND_SLEEP")).reflection(); + } + + @Test + public void testClassParameter() { + assertDefinedParameters(Enclosure.class, Set.of(matchUpperBounds("A", Animal.class))); + } + + @Test + public void testGetStack_ReturnType() { + Predicate typeMatcher = getDefinedTypes(Enclosure.class, ".*").stream() + .map(H09_TestUtils::match) + .reduce(Predicate::or) + .orElse(new H09_TestUtils.GenericPredicate(i -> false, "Expected type is not defined")); + + assertReturnParameter(getStack, matchNested(StackOfObjects.class, typeMatcher)); + } + + @Test + public void testForEach_Parameter() { + Predicate typeMatcher = getDefinedTypes(Enclosure.class, ".*").stream() + .map(type -> matchWildcard(false, type)) + .reduce(Predicate::or) + .orElse(new H09_TestUtils.GenericPredicate(i -> false, "Expected type is not defined")); + + assertParameters(forEach, List.of(matchNested(Consumer.class, typeMatcher))); + } + + @Test + public void testSWIMS_AT_LOW_ELEVATION_Type() { + assertType(swimsAtLowElevation, matchNested(Predicate.class, match(Swims.class))); + } + + @ParameterizedTest + @CsvSource({"5,false", "-3,false", "-5,true", "-5,true"}) + public void testSWIMS_AT_LOW_ELEVATION_Implementation(float elevation, boolean predicateResult) { + assertNotNull(Enclosure.SWIMS_AT_LOW_ELEVATION, emptyContext(), r -> "SWIMS_AT_LOW_ELEVATION is not implemented"); + + try { + Swims mock = mock(Swims.class); + when(mock.getElevation()).thenReturn(elevation); + + Context context = contextBuilder().add("elevation", elevation).build(); + + assertEquals( + predicateResult, + Enclosure.SWIMS_AT_LOW_ELEVATION.test(mock), + context, + r -> "SWIMS_AT_LOW_ELEVATION is not implemented correctly" + ); + + } catch (ClassCastException exception) { + fail( + emptyContext(), + r -> "SWIMS_AT_LOW_ELEVATION does not accept correct type of objects. Message of thrown Exception: %s".formatted( + exception.getMessage()) + ); + } + } + + @Test + public void testFEED_AND_SLEEP_Type() { + assertType(feedAndSleep, matchNested(Consumer.class, match(Animal.class))); + } + + @Test + public void testFEED_AND_SLEEP_Implementation() { + assertNotNull(Enclosure.FEED_AND_SLEEP, emptyContext(), r -> "FEED_AND_SLEEP is not implemented"); + + try { + Animal mock = mock(Animal.class); + + Enclosure.FEED_AND_SLEEP.accept(mock); + + verify(mock, atLeastOnce()).eat(); + verify(mock, atLeastOnce()).sleep(); + + } catch (ClassCastException exception) { + fail( + emptyContext(), + r -> "FEED_AND_SLEEP does not accept correct type of objects. Message of thrown Exception: %s".formatted(exception.getMessage()) + ); + } + } +} diff --git a/H09/src/graderPublic/java/h09/H09_RubricProviderPublic.java b/H09/src/graderPublic/java/h09/H09_RubricProviderPublic.java new file mode 100644 index 0000000..ae4f9e4 --- /dev/null +++ b/H09/src/graderPublic/java/h09/H09_RubricProviderPublic.java @@ -0,0 +1,152 @@ +package h09; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.JUnitTestRef; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; + +import java.util.List; + +import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.criterion; +import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.graderPrivateOnly; + +public class H09_RubricProviderPublic implements RubricProvider { + + public static final Rubric RUBRIC = Rubric.builder() + .title("H09") + .addChildCriteria( + Criterion.builder() + .shortDescription("H9.1 | StackOfObjects") + .addChildCriteria( + criterion( + "Der generische Typparameter O wird korrekt deklariert und das Attribut objs wird korrekt initialisiert.", + JUnitTestRef.and( + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testClassParameter")), + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testObjsType")) + ) + ), + criterion( + "push wird korrekt mit generischem Typparameter angepasst.", + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testPushParameter")) + ), + criterion( + "remove wird korrekt mit generischem Typparameter angepasst.", + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testRemoveParameter")) + ), + criterion( + "get und pop werden korrekt mit generischem Typparameter angepasst.", + JUnitTestRef.and( + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testGetParameter")), + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testPopParameter")) + ) + ), + criterion( + "of wird korrekt mit generischem Typparameter angepasst.", + JUnitTestRef.ofMethod(() -> StackOfObjectsTestPublic.class.getMethod("testOfParameter")) + , 2 + ) + ) + .build(), + Criterion.builder() + .shortDescription("H9.2 | Generische Typen beschränken") + .addChildCriteria( + criterion( + "Der generische Typparameter von Enclosure wird korrekt deklariert und beschränkt.", + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod("testClassParameter")) + ), + criterion( + "Enclosure::getStack von Enclosure wird korrekt mit generischem Typparameter angepasst.", + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod("testGetStack_ReturnType")) + ), + privateCriterion( + "Waterenclosure besitzt einen korrekt beschränkten Typparameter und implementiert Enclosure korrekt.", + 0, + 1 + ), + privateCriterion("Waterenclosure::getStack funktioniert korrekt.", 0, 1), + criterion( + "Waterenclosure::feed funktioniert korrekt.", + JUnitTestRef.ofMethod(() -> WaterEnclosureTestPublic.class.getMethod("testFeed")) + , 2 + ), + criterion( + "Waterenclosure::getMeanElevation funktioniert korrekt.", + JUnitTestRef.ofMethod(() -> WaterEnclosureTestPublic.class.getMethod( + "testGetMeanElevation", + List.class, + double.class + )) + ) + ) + .build(), + Criterion.builder() + .shortDescription("H9.3 | Bearbeitung von Enclosures mit funktionalen Interfaces") + .addChildCriteria( + criterion( + "forEach hat korrekt beschränkte Typparameter.", + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod("testForEach_Parameter")), + 3 + ), + privateCriterion("filterObj hat korrekt beschränkte Typparameter.", 0, 3), + privateCriterion("filterFunc hat korrekt beschränkte Typparameter.", 0, 4), + privateCriterion("filterFunc gibt korrekt ein neues Enclosure mit gefilterten Tieren zurück.", 0, 2) + ) + .build(), + Criterion.builder() + .shortDescription("H9.4 | Predicates and Consumer mit Lambda") + .addChildCriteria( + criterion( + "SWIMS_AT_LOW_ELEVATION funktioniert korrekt und wurde korrekt beschränkt.", + JUnitTestRef.and( + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod("testSWIMS_AT_LOW_ELEVATION_Type")), + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod( + "testSWIMS_AT_LOW_ELEVATION_Implementation", + float.class, + boolean.class + )) + ) + ), + criterion( + "FEED_AND_SLEEP funktioniert korrekt und wurde korrekt beschränkt.", + JUnitTestRef.and( + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod("testFEED_AND_SLEEP_Type")), + JUnitTestRef.ofMethod(() -> EnclosureTestPublic.class.getMethod("testFEED_AND_SLEEP_Implementation")) + ) + ), + privateCriterion("EAT_AND_SINK() gibt einen korrekten Consumer zurück, welcher korrekt beschränkt ist.", 0, 2) + ) + .build(), + Criterion.builder() + .shortDescription("H9.5 | Enclosure::forEach") + .addChildCriteria( + privateCriterion( + "Drei Lion Objekte werden erstellt sowie gefüttert. Die Methode forEach wird grundlegend getestet.", + 0, + 1 + ), + privateCriterion("Zwei Penguin Objekte werden korrekt erstellt, bewegt und gefüttert.", 0, 1), + privateCriterion("Einfache Fehlfunktionen der Methode filterFunc werden erkannt.", 0, 1) + ) + .build() + ) + .build(); + + @Override + public Rubric getRubric() { + return RUBRIC; + } + + public static Criterion privateCriterion(String message, int min, int max) { + return Criterion.builder() + .shortDescription(message) + .grader(graderPrivateOnly(max)) + .minPoints(min) + .maxPoints(max) + .build(); + } + +// @Override +// public void configure(final RubricConfiguration configuration) { +// configuration.addTransformer(new AccessTransformer()); +// } +} diff --git a/H09/src/graderPublic/java/h09/H09_TestUtils.java b/H09/src/graderPublic/java/h09/H09_TestUtils.java new file mode 100644 index 0000000..3454afb --- /dev/null +++ b/H09/src/graderPublic/java/h09/H09_TestUtils.java @@ -0,0 +1,689 @@ +package h09; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import spoon.reflect.declaration.CtField; +import spoon.reflect.declaration.CtMethod; +import spoon.reflect.declaration.CtParameter; +import spoon.reflect.declaration.CtType; +import spoon.reflect.declaration.CtTypeParameter; +import spoon.reflect.reference.CtTypeReference; +import spoon.reflect.visitor.filter.TypeFilter; + +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.emptyContext; + +public class H09_TestUtils { + + /** + * Creates a new Predicate that matches a Type if it has the given name and no bounds. + * + * @param name the name of the Type that should be matched. Also accepts a regex for the name. + * @return a Predicate that matches a Type with the given name. + */ + public static Predicate matchNoBounds(String name) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!type.getTypeName().matches(name)) { + return false; + } + if (bounds.getLeft() != null) { + return false; + } + return bounds.getRight().size() == 1 && bounds.getRight().get(0) == Object.class; + }, + String.format("Name: %s; Bounds: No Bounds", name) + ); + } + + /** + * Creates a new Predicate that matches a Type if it has the given name and bounds. + * + * @param name the name of the Type that should be matched. Also accepts a regex for the name. + * @param expectedBounds the lower Bounds that a type should have to be matched by this Predicate. + * @return a Predicate that matches a Type with the given name and bounds. + */ + public static Predicate matchLowerBounds(String name, Type... expectedBounds) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!type.getTypeName().matches(name)) { + return false; + } + return bounds.getLeft().size() == expectedBounds.length + && new HashSet<>(bounds.getLeft()).containsAll(List.of(expectedBounds)); + }, + String.format( + "Name: %s; Bounds: %s", + name, + Arrays.stream(expectedBounds).map(Type::getTypeName).collect(Collectors.joining(", ")) + ) + ); + } + + /** + * Creates a new Predicate that matches a Type if it has the given name and bounds. + * + * @param name the name of the Type that should be matched. Also accepts a regex for the name. + * @param expectedBounds the upper Bounds that a type should have to be matched by this Predicate. + * @return a Predicate that matches a Type with the given name and bounds. + */ + public static Predicate matchLowerBounds(String name, Predicate... expectedBounds) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!type.getTypeName().matches(name)) { + return false; + } + return bounds.getLeft().size() == expectedBounds.length + && bounds.getLeft() + .stream() + .allMatch(actual -> Stream.of(expectedBounds).anyMatch(expected -> expected.test(actual))) + && Stream.of(expectedBounds).allMatch(expected -> bounds.getLeft().stream().anyMatch(expected)); + }, + String.format( + "Name: %s; Bounds: %s", + name, + Arrays.stream(expectedBounds).map(Object::toString).collect(Collectors.joining(", ")) + ) + ); + } + + /** + * Creates a new Predicate that matches a Type if it has the given name and bounds. + * + * @param name the name of the Type that should be matched. Also accepts a regex for the name. + * @param expectedBounds the upper Bounds that a type should have to be matched by this Predicate. + * @return a Predicate that matches a Type with the given name and bounds. + */ + public static Predicate matchUpperBounds(String name, Type... expectedBounds) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!type.getTypeName().matches(name)) { + return false; + } + return bounds.getRight().size() == expectedBounds.length + && new HashSet<>(bounds.getRight()).containsAll(List.of(expectedBounds)); + }, + String.format( + "Name: %s; Bounds: %s", + name, + Arrays.stream(expectedBounds).map(Type::getTypeName).collect(Collectors.joining(", ")) + ) + ); + } + + /** + * Creates a new Predicate that matches a Type if it has the given name and bounds. + * + * @param name the name of the Type that should be matched. Also accepts a regex for the name. + * @param expectedBounds the upper Bounds that a type should have to be matched by this Predicate. + * @return a Predicate that matches a Type with the given name and bounds. + */ + @SafeVarargs + public static Predicate matchUpperBounds(String name, Predicate... expectedBounds) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!type.getTypeName().matches(name)) { + return false; + } + return bounds.getRight().size() == expectedBounds.length + && bounds.getRight() + .stream() + .allMatch(actual -> Stream.of(expectedBounds).anyMatch(expected -> expected.test(actual))) + && Stream.of(expectedBounds).allMatch(expected -> bounds.getRight().stream().anyMatch(expected)); + }, + String.format( + "Name: %s; Bounds: %s", + name, + Arrays.stream(expectedBounds).map(Object::toString).collect(Collectors.joining(", ")) + ) + ); + } + + /** + * Creates a new Predicate that matches a Type if it is a wildcard type and has the given bounds. + * + * @param isUpperBound indicates if the given Bounds should be the upper or lower bounds of the type + * @param expectedBounds the expected Bounds that a type should have to be matched by this Predicate. + * @return a Predicate that matches a wildcard type with the given bounds. + */ + public static Predicate matchWildcard(boolean isUpperBound, Type... expectedBounds) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!(type instanceof WildcardType wildcardType)) { + return false; + } + if (isUpperBound) { + return bounds.getRight().size() == expectedBounds.length && + new HashSet<>(bounds.getRight()).containsAll(List.of(expectedBounds)); + } + return bounds.getLeft().size() == expectedBounds.length && + new HashSet<>(bounds.getLeft()).containsAll(List.of(expectedBounds)); + }, + String.format( + "Wildcard: ? %s %s", + isUpperBound ? "extends" : "super", + Arrays.stream(expectedBounds).map(Type::getTypeName).collect(Collectors.joining(" & ")) + ) + ); + } + + /** + * Creates a new Predicate that matches a Type if it is a wildcard type and has the given bounds. + * + * @param isUpperBound indicates if the given Bounds should be the upper or lower bounds of the type + * @param expectedBounds the expected Bounds that a type should have to be matched by this Predicate. + * @return a Predicate that matches a wildcard type with the given bounds. + */ + @SafeVarargs + public static Predicate matchWildcard(boolean isUpperBound, Predicate... expectedBounds) { + return new GenericPredicate( + (type) -> { + Pair, List> bounds = getBounds(type); + if (!(type instanceof WildcardType wildcardType)) { + return false; + } + if (isUpperBound) { + return bounds.getRight().size() == expectedBounds.length + && bounds.getRight() + .stream() + .allMatch(actual -> Stream.of(expectedBounds).anyMatch(expected -> expected.test(actual))) + && Stream.of(expectedBounds).allMatch(expected -> bounds.getRight().stream().anyMatch(expected)); + } + return bounds.getLeft().size() == expectedBounds.length + && bounds.getLeft() + .stream() + .allMatch(actual -> Stream.of(expectedBounds).anyMatch(expected -> expected.test(actual))) + && Stream.of(expectedBounds).allMatch(expected -> bounds.getLeft().stream().anyMatch(expected)); + }, + String.format( + "Wildcard: ? %s %s", + isUpperBound ? "extends" : "super", + Arrays.stream(expectedBounds).map(Object::toString).collect(Collectors.joining(" & ")) + ) + ); + } + + /** + * Creates a new Predicate that matches a Type if it is an exact match with the given Type. + * + * @param expected the type that is expected. + * @return the Predicate matching the expected type. + */ + public static Predicate match(Type expected) { + return new GenericPredicate( + (type) -> type.equals(expected), + String.format("Type: %s", expected.getTypeName()) + ); + } + + /** + * Creates a new Predicate that matches a Type if it is a match with an array of the given Type. + * + * @param expected the type that is expected. + * @return the Predicate matching the expected type. + */ + public static Predicate matchArray(Type expected) { + return new GenericPredicate( + (type) -> { + if (type instanceof GenericArrayType arrayType) { + return arrayType.getGenericComponentType().equals(expected); + } + return false; + }, + String.format("Type: %s", expected.getTypeName()) + ); + } + + /** + * Creates a new Predicate that matches a Type if it is a match with an array of the given Type. + * + * @param expected the type that is expected. + * @return the Predicate matching the expected type. + */ + public static Predicate matchArray(Predicate expected) { + return new GenericPredicate( + (type) -> { + if (type instanceof GenericArrayType arrayType) { + return expected.test(arrayType.getGenericComponentType()); + } + return false; + }, + String.format("Type: %s", expected.toString()) + ); + } + + /** + * Creates a new Predicate that matches a Type if it has the expected outer Type and the inner Types all match the + * expectedNested types + * + * @param outerType the Type of the outer type. + * @param expectedNested an array of predicates for all inner types that should be matched. + * @return a predicate that checks the outer and inner types of a ParameterizedType. + */ + @SafeVarargs + public static Predicate matchNested(Type outerType, Predicate... expectedNested) { + return new Predicate<>() { + @Override + public boolean test(Type type) { + if (!(type instanceof ParameterizedType parameterizedType)) { + return false; + } + if (!parameterizedType.getRawType().equals(outerType)) { + return false; + } + Type[] actualType = parameterizedType.getActualTypeArguments(); + for (int i = 0; i < expectedNested.length; i++) { + if (!expectedNested[i].test(actualType[i])) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return String.format("Type: %s; Inner Type: %s", outerType.getTypeName(), List.of(expectedNested)); + } + }; + } + + /** + * Matches if any of the supplied Types is passed to the predicate + * + * @param typesToMatch the types to match + * @return a Predicate that checks if one of the supplied Types is tested + */ + public static Predicate matchAny(Type... typesToMatch) { + return Arrays.stream(typesToMatch) + .map(H09_TestUtils::match) + .reduce(Predicate::or) + .orElse(new H09_TestUtils.GenericPredicate(i -> false, "Expected type is not defined")); + } + + /** + * Matches if any of the supplied Types is passed to the predicate + * + * @param typesToMatch the types to match + * @return a Predicate that checks if one of the supplied Types is tested + */ + public static Predicate matchAny(List typesToMatch) { + return typesToMatch.stream() + .map(H09_TestUtils::match) + .reduce(Predicate::or) + .orElse(new H09_TestUtils.GenericPredicate(i -> false, "Expected type is not defined")); + } + + /** + * This method returns the upper and lower bounds of the given type. + * + *

The returned Pair contains a list of lower bounds in the left Parameter and a list of upper bounds in the right + * Parameter. + * + *

If the given Type does not have any lower bounds the left element of the Pair will be null. + * + *

If the given Type is not generic this method will return null. + * + * @param type the type to getrieve the Bounds from + * @return a Pair containing both the upper and the lower bounds of the given Type + */ + public static Pair, List> getBounds(Type type) { + if (type instanceof WildcardType wildcardType) { + return ImmutablePair.of(Arrays.asList(wildcardType.getLowerBounds()), Arrays.asList(wildcardType.getUpperBounds())); + } + if (type instanceof ParameterizedType parameterizedType) { + return ImmutablePair.of(null, Arrays.asList(parameterizedType.getActualTypeArguments())); + } + if (type instanceof TypeVariable typeVariable) { + return ImmutablePair.of(null, Arrays.asList(typeVariable.getBounds())); + } + if (type instanceof GenericArrayType) { + return ImmutablePair.of(null, List.of(Object[].class)); + } + return null; + } + + /** + * Retrieves the inner type of the given Type. + * + * @param type the type to get the inner type from. + * @return the inner type of the given type. Returns empty list if no inner type is present. + */ + public static List getInnerTypes(Type type) { + if (!(type instanceof ParameterizedType parameterizedType)) { + return List.of(); + } + return Arrays.asList(parameterizedType.getActualTypeArguments()); + } + + /** + * Retrieves the super Types of the given Type if it is a class. Returns upper bounds otherwise. + * + * @param type the type to get the super types from. + * @return the super types or upper bounds of the given type. Returns a list containing only Object if no supertype can be + * determined. + */ + public static List getGenericSuperTypes(Type type) { + if (type instanceof Class clazz) { + List superTypes = new ArrayList<>(); + if (clazz.getGenericSuperclass() != null) { + superTypes.add(clazz.getGenericSuperclass()); + } + if (clazz.getGenericInterfaces().length > 0) { + superTypes.addAll(List.of(clazz.getGenericInterfaces())); + } + return superTypes; + } + + Pair, List> bounds = getBounds(type); + if (bounds != null) { + return bounds.getRight(); + } + return List.of(Object.class); + } + + /** + * Retrieves the return type of the given Method. + * + * @param method the method to get the return type from. + * @return the return type of the given method. + */ + public static Type getReturnType(Method method) { + return method.getGenericReturnType(); + } + + /** + * Retrieves all parameters of the given method. Returned parameters may not generic. + * + * @param method the method that the generic types should be retrieved from. + * @param regex a regex that is used to filter all generic type names. + * @return a List containing all types of the parameters from the method whose type names match the given regex. + */ + public static List getTypeParameters(Method method, String regex) { + return Arrays.stream(method.getGenericParameterTypes()).filter(t -> t.getTypeName().matches(regex)).toList(); + } + + /** + * Retrieves all generic types that are defined by the given method. + * + * @param method the method that the generic types should be retrieved from. + * @param regex a regex that is used to filter all generic type names. + * @return a List containing all defined types that match the given regex. + */ + public static List getDefinedTypes(Method method, String regex) { + return Arrays.stream(method.getTypeParameters()).filter(t -> t.getTypeName().matches(regex)).map(t -> (Type) t).toList(); + } + + /** + * Retrieves all generic types that are defined by the given class. + * + * @param clazz the class that the generic types should be retrieved from. + * @param regex a regex that is used to filter all generic type names. + * @return a List containing all defined types that match the given regex. + */ + public static List getDefinedTypes(Class clazz, String regex) { + return Arrays.stream(clazz.getTypeParameters()).filter(t -> t.getTypeName().matches(regex)).map(t -> (Type) t).toList(); + } + + /** + * Asserts that the given {@link Class} defines a certain set a generic Parameters. + * + * @param clazz the Class that should be tested. + * @param expected a set of predicates that is used to check if all defined generic Types match an expected Type. + */ + public static void assertDefinedParameters(Class clazz, Set> expected) { + + List> typeVariable = Arrays.asList(clazz.getTypeParameters()); + CtType ctClass = (CtType) BasicTypeLink.of(clazz).getCtElement(); + var actualNames = + ctClass.getFormalCtTypeParameters().stream().map(CtType::toStringDebug).map(s -> s.replace("\n", "")).toList(); + Context context = contextBuilder() + .add("expected", expected) + .add("actual", actualNames) + .build(); + + assertTrue( + !typeVariable.isEmpty(), + emptyContext(), + r -> clazz.getSimpleName() + " does not have any generic parameters." + ); + + assertEquals( + expected.size(), + typeVariable.size(), + context, + r -> clazz.getSimpleName() + " does not have the expected number of generic parameters." + ); + typeVariable.forEach(a -> + assertTrue( + expected.stream().anyMatch(e -> e.test(a)), + context, + r -> String.format("The type parameter %s of %s do not match any expected types.", a, clazz.getSimpleName()) + ) + ); + } + + /** + * Asserts that the given {@link Method} defines a specific set of generic types. + * + * @param method the method that is checked for type definitions. + * @param expected a set of predicates that is used to check if all defined generic Types match an expected Type. + */ + public static void assertDefinedParameters(Method method, Set> expected) { + + List> typeVariable = Arrays.asList(method.getTypeParameters()); + CtMethod ctMethod = BasicMethodLink.of(method).getCtElement(); + var actualNames = ctMethod.getFormalCtTypeParameters() + .stream() + .map(CtTypeParameter::toStringDebug) + .map(s -> s.replace("\n", "")) + .toList(); + Context context = contextBuilder() + .add("expected", expected) + .add("actual", actualNames) + .build(); + + assertTrue(!typeVariable.isEmpty(), emptyContext(), r -> method.getName() + " does not have any generic parameters."); + + assertEquals( + expected.size(), + typeVariable.size(), + context, + r -> method.getName() + " does not have the expected number of generic parameters." + ); + typeVariable.forEach(a -> + assertTrue( + expected.stream().anyMatch(e -> e.test(a)), + context, + r -> String.format("The type parameter %s of %s do not match any expected types.", a, method.getName()) + ) + ); + } + + /** + * Asserts that the given {@link Method} has a return type that matches the given {@link Predicate}. + * + * @param method the method that should be tested. + * @param expected the {@link Predicate} that shoul be used to check the return type. + */ + public static void assertReturnParameter(Method method, Predicate expected) { + Type type = method.getGenericReturnType(); + + CtMethod ctMethod = BasicMethodLink.of(method).getCtElement(); + var actualNames = ctMethod.getType().toStringDebug().replace("\n", ""); + Context context = contextBuilder() + .add("actual type", actualNames) + .add("expected", expected) + .build(); + + assertTrue(expected.test(type), context, r -> String.format("%s has a wrong return type.", method.getName())); + } + + /** + * Asserts that the given {@link Method} has a correct list of parameters each parameter is checked with the given + * {@link Predicate} for the index. + * + * @param method the method that should be checked + * @param expected a list containing a {@link Predicate} for each Parameter of the method. + */ + public static void assertParameters(Method method, List> expected) { + Type[] type = method.getGenericParameterTypes(); + + assertEquals( + expected.size(), + type.length, + emptyContext(), r -> String.format("The method %s() does not have the correct amount of parameters", method.getName()) + ); + + CtMethod ctMethod = BasicMethodLink.of(method).getCtElement(); + var actualNames = + ctMethod.getParameters() + .stream() + .map(CtParameter::getType) + .map(CtTypeReference::toStringDebug) + .map(s -> s.replace("\n", "")) + .toList(); + + for (int i = 0; i < type.length; i++) { + int finalI = i; + + Context context = contextBuilder() + .add("actual type", actualNames.get(i)) + .add("expected", expected.get(i)) + .build(); + + assertTrue( + expected.get(i).test(type[i]), + context, + r -> String.format("%s has a wrong parameter at index %d.", method.getName(), finalI) + ); + } + + } + + /** + * Asserts that the given field has a {@link Type} that matches the given {@link Predicate}. + * + * @param field the field that should be checked. + * @param expected the {@link Predicate} that is used to check if the Field has a correct Type. + */ + public static void assertType(Field field, Predicate expected) { + Type type = field.getGenericType(); + + CtField ctField = + BasicTypeLink.of(field.getDeclaringClass()).getCtElement().filterChildren(new TypeFilter<>(CtField.class) { + @Override + public boolean matches(CtField element) { + return super.matches(element) && element.getSimpleName().equals(field.getName()); + } + }).first(); + var actualNames = ctField.getType().toStringDebug(); + + Context context = contextBuilder() + .add("actual type", actualNames) + .add("expected", expected) + .build(); + + assertTrue(expected.test(type), context, r -> String.format("%s has a wrong type.", field.getName())); + + } + + /** + * Asserts that the given method is generic. + * + * @param toTest a method reference to the method that should be checked. + */ + public static void assertGeneric(Method toTest) { + + Predicate isGeneric = (method) -> !getTypeParameters(method, ".*").isEmpty(); + isGeneric = isGeneric.or((method) -> getBounds(getReturnType(method)) != null); + + assertTrue( + isGeneric.test(toTest), + emptyContext(), + r -> String.format("The method %s() is not Generic.", toTest.getName()) + ); + } + + /** + * A simple Predicate that can store a custom toString() method for better readability. + */ + public static class GenericPredicate implements Predicate { + + /** + * The description that should be displayed if toString() is called. + */ + private final String description; + /** + * The underlying predicate. + */ + private final Predicate predicate; + + /** + * Creates a new {@link GenericPredicate} from a {@link Predicate} and a short description that describes what the + * predicate matches. + * + * @param predicate the predicate that should be used to match any object. + * @param description the description of what the predicate matches. + */ + GenericPredicate(Predicate predicate, String description) { + this.predicate = predicate; + this.description = description; + } + + @Override + public boolean test(Type type) { + return predicate.test(type); + } + + @NotNull + @Override + public Predicate and(@NotNull Predicate other) { + return new GenericPredicate(predicate.and(other), "(" + this.description + " and " + other + ")"); + } + + @NotNull + @Override + public Predicate negate() { + return new GenericPredicate(predicate.negate(), "(not " + description + ")"); + } + + @NotNull + @Override + public Predicate or(@NotNull Predicate other) { + return new GenericPredicate(predicate.or(other), "(" + this.description + " or " + other + ")"); + } + + @Override + public String toString() { + return description; + } + } +} diff --git a/H09/src/graderPublic/java/h09/ReflectionUtils.java b/H09/src/graderPublic/java/h09/ReflectionUtils.java new file mode 100644 index 0000000..9160c90 --- /dev/null +++ b/H09/src/graderPublic/java/h09/ReflectionUtils.java @@ -0,0 +1,191 @@ +package h09; + +import com.google.common.primitives.Primitives; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.List; +import java.util.Optional; + +public class ReflectionUtils { + + public static void setFieldValue(Object instance, String fieldName, Object value) { + try { + Class objectClass = instance.getClass(); + Field declaredField; + try { + declaredField = objectClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + declaredField = getSuperClassesIncludingSelf(objectClass).stream() + .filter((c) -> List.of(c.getDeclaredFields()).stream() + .map(Field::getName) + .anyMatch(name -> name.equals(fieldName)) + ) + .map((c) -> { + try { + return c.getDeclaredField(fieldName); + } catch (NoSuchFieldException ex) { + throw new RuntimeException(ex); + } + }) + .findFirst() + .orElseThrow(() -> new NoSuchFieldException(e.getMessage())); + } + + //best case field in non Final + if (!Modifier.isFinal(declaredField.getModifiers())) { + try { + declaredField.setAccessible(true); + declaredField.set(instance, value); + return; + } catch (Exception ignored) { + } + } + + //field has setter + Optional setter = Arrays + .stream(objectClass.getDeclaredMethods()) + .filter( + m -> m.getName().equalsIgnoreCase("set" + fieldName) + ).findFirst(); + if (setter.isPresent()) { + setter.get().invoke(instance, value); + return; + } + + //rely on Unsafe to set value + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe) unsafeField.get(null); + + Field theInternalUnsafeField = Unsafe.class.getDeclaredField("theInternalUnsafe"); + theInternalUnsafeField.setAccessible(true); + Object theInternalUnsafe = theInternalUnsafeField.get(null); + + Method offset = Class.forName("jdk.internal.misc.Unsafe").getMethod("objectFieldOffset", Field.class); + unsafe.putBoolean(offset, 12, true); + + switch (value) { + case Boolean val -> unsafe.putBoolean(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Character val -> unsafe.putChar(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Short val -> unsafe.putShort(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Integer val -> unsafe.putInt(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Long val -> unsafe.putLong(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Double val -> unsafe.putDouble(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Float val -> unsafe.putFloat(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + default -> unsafe.putObject(instance, (long) offset.invoke(theInternalUnsafe, declaredField), value); + } + } catch (IllegalAccessException | NoSuchFieldException | ClassNotFoundException | NoSuchMethodException | + InvocationTargetException e) { + e.printStackTrace(); + } + } + + public static T getFieldValue(Object instance, String fieldName) { + Field f; + Class fieldType = null; + try { + f = instance.getClass().getDeclaredField(fieldName); + + try { + f.setAccessible(true); + return (T) f.get(instance); + } catch (Exception ignored) { + } + + fieldType = f.getType(); + if (Primitives.isWrapperType(fieldType)) { + fieldType = Primitives.unwrap(fieldType); + } + + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe) unsafeField.get(null); + + Field theInternalUnsafeField = Unsafe.class.getDeclaredField("theInternalUnsafe"); + theInternalUnsafeField.setAccessible(true); + Object theInternalUnsafe = theInternalUnsafeField.get(null); + + Method offset = Class.forName("jdk.internal.misc.Unsafe").getMethod("objectFieldOffset", Field.class); + unsafe.putBoolean(offset, 12, true); + + Object fieldValue; + if (boolean.class == fieldType) { + fieldValue = unsafe.getBoolean(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (byte.class == fieldType) { + fieldValue = unsafe.getByte(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (short.class == fieldType) { + fieldValue = unsafe.getShort(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (int.class == fieldType) { + fieldValue = unsafe.getInt(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (long.class == fieldType) { + fieldValue = unsafe.getLong(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (float.class == fieldType) { + fieldValue = unsafe.getFloat(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (double.class == fieldType) { + fieldValue = unsafe.getDouble(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else if (char.class == fieldType) { + fieldValue = unsafe.getChar(instance, (long) offset.invoke(theInternalUnsafe, f)); + } else { + fieldValue = unsafe.getObject(instance, (long) offset.invoke(theInternalUnsafe, f)); + } + return (T) fieldValue; + } catch (NoSuchFieldException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | + IllegalAccessException e) { + throw new RuntimeException( + "Could not set value for Field %s(%s) in %s. Please do not access this field.".formatted( + fieldName, + fieldType, + instance.getClass() + ), e + ); + } + } + + public static void copyFields(Object source, Object dest) { + for (Field f : source.getClass().getDeclaredFields()) { + setFieldValue(dest, f.getName(), getFieldValue(source, f.getName())); + } + } + + public static boolean actsLikePrimitive(Class type) { + return type.isPrimitive() || + Enum.class.isAssignableFrom(type) || + Primitives.isWrapperType(type) || + type == String.class; + } + + public static List> getSuperClassesIncludingSelf(Class clazz) { + List> classes = new ArrayList<>(); + Deque> classDeque = new ArrayDeque<>(); + + classDeque.add(clazz); + + while ((clazz = classDeque.peekFirst()) != null) { + classDeque.pop(); + + classes.add(clazz); + if (clazz.getSuperclass() != null) { + classDeque.add(clazz.getSuperclass()); + } + if (clazz.getInterfaces().length > 0) { + classDeque.addAll(List.of(clazz.getInterfaces())); + } + + } + return classes; + } + + public static boolean isObjectMethod(Method methodToCheck) { + List objectMethods = + List.of("getClass", "hashCode", "equals", "clone", "toString", "notify", "notifyAll", "wait", "finalize"); + return objectMethods.contains(methodToCheck.getName()); + } +} diff --git a/H09/src/graderPublic/java/h09/StackOfObjectsTestPublic.java b/H09/src/graderPublic/java/h09/StackOfObjectsTestPublic.java new file mode 100644 index 0000000..8dee2e6 --- /dev/null +++ b/H09/src/graderPublic/java/h09/StackOfObjectsTestPublic.java @@ -0,0 +1,101 @@ +package h09; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; + +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Set; + +import static h09.H09_TestUtils.assertDefinedParameters; +import static h09.H09_TestUtils.assertParameters; +import static h09.H09_TestUtils.assertReturnParameter; +import static h09.H09_TestUtils.assertType; +import static h09.H09_TestUtils.getTypeParameters; +import static h09.H09_TestUtils.match; +import static h09.H09_TestUtils.matchArray; +import static h09.H09_TestUtils.matchNested; +import static h09.H09_TestUtils.matchNoBounds; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertNotNull; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.emptyContext; +import static org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers.identical; + +@TestForSubmission +public class StackOfObjectsTestPublic { + + BasicTypeLink stackLink; + Class ctClassStack; + Method get; + Method pop; + Method push; + Method remove; + Method of; + Field objs; + + + @BeforeEach + public void setUp() { + stackLink = BasicTypeLink.of(StackOfObjects.class); + ctClassStack = stackLink.reflection(); + get = stackLink.getMethod(identical("get")).reflection(); + pop = stackLink.getMethod(identical("pop")).reflection(); + push = stackLink.getMethod(identical("push")).reflection(); + remove = stackLink.getMethod(identical("remove")).reflection(); + of = stackLink.getMethod(identical("of")).reflection(); + objs = stackLink.getField(identical("objs")).reflection(); + } + + @Test + public void testClassParameter() { + assertDefinedParameters(ctClassStack, Set.of(matchNoBounds("O"))); + } + + @Test + public void testObjsType() { + assertType(objs, matchArray(matchNoBounds("O"))); + assertNotNull( + ReflectionUtils.getFieldValue(new StackOfObjects<>(), "objs"), + emptyContext(), + r -> "Field objs is not correctly initialized" + ); + } + + @Test + public void testPushParameter() { + assertParameters(push, List.of(matchNoBounds("O"))); + } + + @Test + public void testRemoveParameter() { + assertParameters(remove, List.of(matchNoBounds("O"))); + } + + @Test + public void testPopParameter() { + assertReturnParameter(pop, matchNoBounds("O")); + } + + @Test + public void testGetParameter() { + assertReturnParameter(get, matchNoBounds("O")); + } + + @Test + public void testOfParameter() { + assertDefinedParameters(of, Set.of(matchNoBounds("O"))); + + List types = getTypeParameters(of, ".*"); + + assertReturnParameter( + of, + matchNested(StackOfObjects.class, match(((GenericArrayType) types.get(0)).getGenericComponentType())) + ); + + assertParameters(of, List.of(match(types.get(0)))); + } +} diff --git a/H09/src/graderPublic/java/h09/WaterEnclosureTestPublic.java b/H09/src/graderPublic/java/h09/WaterEnclosureTestPublic.java new file mode 100644 index 0000000..deccde2 --- /dev/null +++ b/H09/src/graderPublic/java/h09/WaterEnclosureTestPublic.java @@ -0,0 +1,140 @@ +package h09; + +import h09.abilities.Swims; +import h09.animals.Penguin; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static org.mockito.Mockito.CALLS_REAL_METHODS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.fail; +import static org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers.identical; + +@TestForSubmission +public class WaterEnclosureTestPublic { + + BasicTypeLink waterEnclosureLink; + Class waterEnclosureClass; + Method getStack; + Method feed; + Method getMeanElevation; + Field animals; + + + @BeforeEach + public void setUp() { + waterEnclosureLink = BasicTypeLink.of(WaterEnclosure.class); + waterEnclosureClass = waterEnclosureLink.reflection(); + getStack = waterEnclosureLink.getMethod(identical("getStack")).reflection(); + feed = waterEnclosureLink.getMethod(identical("feed")).reflection(); + getMeanElevation = waterEnclosureLink.getMethod(identical("getMeanElevation")).reflection(); + animals = waterEnclosureLink.getField(identical("animals")).reflection(); + } + + @Test + public void testFeed() { + + WaterEnclosure enclosure = new WaterEnclosure(); + List animals = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + Penguin mock = mock(Penguin.class, CALLS_REAL_METHODS); + ReflectionUtils.setFieldValue(mock, "isHungry", false); + ReflectionUtils.setFieldValue(mock, "elevation", Swims.MAX_ELEVATION); + if (i % 2 == 0) { + ReflectionUtils.setFieldValue(mock, "isHungry", true); + } + if (i % 3 == 0) { + ReflectionUtils.setFieldValue(mock, "elevation", Swims.MIN_ELEVATION); + } + + enclosure.getStack().push(mock); + animals.add(mock); + } + + Context context = contextBuilder() + .add("Animals", animals) + .build(); + + enclosure.feed(); + + for (int i = 0; i < 10; i++) { + if (enclosure.getStack().size() <= 0) { + fail(context, r -> "WaterEnclosure does not have correct number of Animals after feeding."); + } + Penguin mock = (Penguin) enclosure.getStack().pop(); + + int id = animals.indexOf(mock); + + if (id % 2 == 0) { + verify(mock).eat(); + verify(mock).swimDown(); + if (i % 3 == 0) { + verify(mock).swimUp(); + } else { + verify(mock, never()).swimUp(); + } + } else { + verify(mock, never()).eat(); + } + } + } + + @ParameterizedTest + @MethodSource("provide_testGetMeanElevation") + public void testGetMeanElevation(List elevations, double expected) { + + WaterEnclosure enclosure = new WaterEnclosure<>(); + + for (double elevation : elevations) { + Penguin mock = mock(Penguin.class); + when(mock.getElevation()).thenReturn((float) elevation); + + enclosure.getStack().push(mock); + } + + float actual = enclosure.getMeanElevation(); + + Context context = contextBuilder() + .add("Elevations", elevations) + .build(); + + double error = 0.00001; + + assertTrue( + Math.abs(Math.abs(expected) - Math.abs(actual)) < error, + context, + r -> "Average Elevation is not calculated correctly." + ); + } + + public static Stream provide_testGetMeanElevation() { + return Stream.of( + Arguments.of(List.of(0d, 0d, 0d, 0d, 0d, 0d), 0.0), + Arguments.of(List.of(0d, -1d, -2d, -3d, -4d, -5d), -2.5), + Arguments.of(List.of(-1d, -2d, -3d, -4d, -5d, -6d), -3.5), + Arguments.of(List.of(-6d, -5d, -4d, -3d, -2d, -1d), -3.5), + Arguments.of(List.of(-3d, -5d, 0d, -3d, -10d, -1d), -3.6666667), + Arguments.of(List.of(-3d, -2d, 0d, -3d, -2d, -3d), -2.1666667), + Arguments.of(List.of(-2d, -2d, -2d, -2d, -2d, -2d), -2.0), + Arguments.of(List.of(-1d, -2d, -2d), -1.6666666) + ); + } +} diff --git a/H09/src/main/java/h09/Enclosure.java b/H09/src/main/java/h09/Enclosure.java new file mode 100644 index 0000000..561255d --- /dev/null +++ b/H09/src/main/java/h09/Enclosure.java @@ -0,0 +1,119 @@ +package h09; + +import h09.animals.Animal; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.Supplier; + +/** + * An object of a class implementing {@link Enclosure} has the ability to contain and manage a stack of {@link Animal}s. + */ +// TODO: H9.2.1 +public interface Enclosure { + /** + * @return the stack of animals which is used manage the contained {@link Animal}s + */ + @StudentImplementationRequired("H9.2.1") + // TODO: H9.2.1 + StackOfObjects getStack(); + + /** + * Feeds all contained animals. + */ + @DoNotTouch + void feed(); + + /** + * Counts the number of hungry {@link Animal}s in the enclosure. + * + * @return number of hungry {@link Animal}s in the enclosure + */ + @DoNotTouch + @SuppressWarnings("RedundantCast") + default int countHungry() { + int count = 0; + for (int i = 0; i < this.getStack().size(); i++) + if (((Animal) this.getStack().get(i)).isHungry()) count++; + return count; + } + + + /** + * Applies a {@link Consumer} operation on each {@link Animal} in the enclosure. + * + * @param func operation to be applied to each {@link Animal} in the enclosure + */ + @StudentImplementationRequired("H9.3.1") // TODO: H9.3.1 + default void forEach(Consumer func) { + for (int i = 0; i < this.getStack().size(); i++) + func.accept(this.getStack().get(i)); + } + + /** + * Tests a {@link Predicate} operation on each {@link Animal} in the enclosure and removes every {@link Animal} + * which does not satisfy the predicate. That means only {@link Animal}s for which the predicate returns 'true' + * remain in the enclosure. + * + * @param filter operation to test to each {@link Animal} in the enclosure + */ + @StudentImplementationRequired("H9.3.2") // TODO: H9.3.2 + default void filterObj(Predicate filter) { + for (int i = 0; i < this.getStack().size(); i++) { + Object a = this.getStack().get(i); + if (!filter.test(a)) { + this.getStack().remove(a); + i--; + } + } + } + + /** + * Returns a new {@link Enclosure} that contains only the {@link Animal}s of the previous {@link Enclosure} which + * satisfied the predicate. That means only {@link Animal}s for which the predicate returns 'true' are included + * in the new enclosure. + * + * @param supp {@link Supplier} which is used to create the new {@link Enclosure} to be returned + * @param filter operation to test to each {@link Animal} in the enclosure + * @param Type of the new {@link Enclosure} which is returned + * @return a new {@link Enclosure} that contains only the {@link Animal}s of the previous {@link Enclosure} which + * satisfied the predicate + */ + @StudentImplementationRequired("H9.3.3") + default Enclosure filterFunc(Supplier supp, Predicate filter) { + // TODO: H9.3.3 + return org.tudalgo.algoutils.student.Student.crash("H9.3.3 - Remove if implemented"); + } + + /** + * {@link Predicate} which returns true if an {@link Animal} is old (that means older than 10). + */ + @DoNotTouch + Predicate IS_OLD = animal -> animal.getAge() > 10; + + /** + * {@link Predicate} which returns true if a swimming {@link Animal} swims at a low elevation. + */ + @StudentImplementationRequired("H9.4.1") // TODO: H9.4.1 + Predicate SWIMS_AT_LOW_ELEVATION = null; + + /** + * {@link Consumer} which lets the consumed {@link Animal} eat and sleep. + */ + @StudentImplementationRequired("H9.4.2") // TODO: H9.4.2 + Consumer FEED_AND_SLEEP = null; + + /** + * Returns a {@link Consumer} which lets the consumed swimming {@link Animal} eat and swim down. + * + * @param Type of the swimming {@link Animal} to eat and swim down + * @return a {@link Consumer} which lets the consumed swimming {@link Animal} eat and swim down + */ + @StudentImplementationRequired("H9.4.3") + static Consumer EAT_AND_SINK() { + // TODO: H9.4.3 + return org.tudalgo.algoutils.student.Student.crash("H9.4.3 - Remove if implemented"); + } +} diff --git a/H09/src/main/java/h09/GroundEnclosure.java b/H09/src/main/java/h09/GroundEnclosure.java new file mode 100644 index 0000000..e1eb063 --- /dev/null +++ b/H09/src/main/java/h09/GroundEnclosure.java @@ -0,0 +1,40 @@ +package h09; + +import h09.abilities.Walks; +import h09.animals.Animal; + +/** + * An object of a class implementing {@link GroundEnclosure} has the ability to contain and manage a stack of + * {@link Animal}s which have the ability to {@link Walks}. + */ +public class GroundEnclosure implements Enclosure { + /** + * The stack of animals which is used manage the contained Animals. + */ + final StackOfObjects animals = new StackOfObjects<>(); + + @Override + public StackOfObjects getStack() { + return animals; + } + + @Override + public void feed() { + for (int i = 0; i < this.getStack().size(); i++) { + A a = (A) this.getStack().get(i); + a.eat(); + } + } + + /** + * Counts the total number of legs of all {@link Animal}s in the enclosure. + * + * @return the total number of legs of all {@link Animal}s in the enclosure + */ + public int countLegs() { + int sum = 0; + for (int i = 0; i < this.getStack().size(); i++) + sum += ((A) this.getStack().get(i)).getNumberOfLegs(); + return sum; + } +} diff --git a/H09/src/main/java/h09/Main.java b/H09/src/main/java/h09/Main.java new file mode 100644 index 0000000..7433c2e --- /dev/null +++ b/H09/src/main/java/h09/Main.java @@ -0,0 +1,15 @@ +package h09; + +/** + * Main entry point in executing the program. + */ +public class Main { + /** + * Main entry point in executing the program. + * + * @param args program arguments, currently ignored + */ + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/H09/src/main/java/h09/StackOfObjects.java b/H09/src/main/java/h09/StackOfObjects.java new file mode 100644 index 0000000..9094f82 --- /dev/null +++ b/H09/src/main/java/h09/StackOfObjects.java @@ -0,0 +1,90 @@ +package h09; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +/** + * An object of class {@link StackOfObjects} represents a data structure of type stack. + */ +@SuppressWarnings({"ManualArrayCopy"}) +public class StackOfObjects { + @StudentImplementationRequired("H9.1.1") // TODO: H9.1.1 + private Object[] objs = new Object[0]; + + /** + * Pushes the given object on this stack. + * + * @param obj the object + */ + @StudentImplementationRequired("H9.1.2") // TODO: H9.1.2 + public void push(Object obj) { + Object[] newArray = new Object[objs.length + 1]; + for (int i = 0; i < objs.length; i++) newArray[i] = objs[i]; + newArray[objs.length] = obj; + objs = newArray; + } + + /** + * Removes the given object from this stack. + * + * @param obj the object + */ + @StudentImplementationRequired("H9.1.3") // TODO: H9.1.3 + public void remove(Object obj) { + Object[] newArray = new Object[objs.length - 1]; + int n = 0; + for (Object currObj : objs) { + if (currObj == obj) continue; + newArray[n++] = currObj; + } + objs = newArray; + } + + /** + * Returns the number of objects in this stack. + * + * @return the number of objects + */ + @DoNotTouch + public int size() { + return objs.length; + } + + /** + * Returns the object at the given index in this stack. + * + * @param index the index + * @return the object + */ + @StudentImplementationRequired("H9.1.4") // TODO: H9.1.4 + public Object get(int index) { + return objs[index]; + } + + /** + * Removes and returns the top object of this stack. + * + * @return the top object + */ + @StudentImplementationRequired("H9.1.4") // TODO: H9.1.4 + public Object pop() { + Object o = get(objs.length - 1); + remove(o); + return o; + } + + /** + * Constructs and returns a stack with the given objects. + * The last object is the top object. + * + * @param objs the objects + * @return the stack + */ + @SafeVarargs + @StudentImplementationRequired("H9.1.5") // TODO: H9.1.5 + public static StackOfObjects of(Object... objs) { + StackOfObjects stack = new StackOfObjects(); + stack.objs = objs; + return stack; + } +} diff --git a/H09/src/main/java/h09/WaterEnclosure.java b/H09/src/main/java/h09/WaterEnclosure.java new file mode 100644 index 0000000..9d4a468 --- /dev/null +++ b/H09/src/main/java/h09/WaterEnclosure.java @@ -0,0 +1,43 @@ +package h09; + +import h09.abilities.Swims; +import h09.animals.Animal; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +/** + * An object of a class implementing {@link WaterEnclosure} has the ability to contain and manage a stack of + * {@link Animal}s which have the ability to {@link Swims}. + */ +// TODO: H9.2.2 +public class WaterEnclosure { + /** + * The stack of animals which is used manage the contained Animals. + */ + @StudentImplementationRequired("H9.2.2") // TODO: H9.2.2 + final StackOfObjects animals = null; + + @StudentImplementationRequired("H9.2.2") + // @Override + public StackOfObjects getStack() { + // TODO: H9.2.2 + return org.tudalgo.algoutils.student.Student.crash("H9.2.2 - Remove if implemented"); + } + + @StudentImplementationRequired("H9.2.2") + // @Override + public void feed() { + // TODO: H9.2.2 + org.tudalgo.algoutils.student.Student.crash("H9.2.2 - Remove if implemented"); + } + + /** + * Compares the elevations of all {@link Animal}s in the enclosure and returns the mean. + * + * @return the mean elevation of all {@link Animal}s in the enclosure + */ + @StudentImplementationRequired("H9.2.2") + public float getMeanElevation() { + // TODO: H9.2.2 + return org.tudalgo.algoutils.student.Student.crash("H9.2.2 - Remove if implemented"); + } +} diff --git a/H09/src/main/java/h09/abilities/Flies.java b/H09/src/main/java/h09/abilities/Flies.java new file mode 100644 index 0000000..ebec1b2 --- /dev/null +++ b/H09/src/main/java/h09/abilities/Flies.java @@ -0,0 +1,18 @@ +package h09.abilities; + +public interface Flies { + /** + * Lets the animal land. + */ + void land(); + + /** + * Lets the animal fly. + */ + void takeOff(); + + /** + * @return whether the animal is flying. + */ + boolean isFlying(); +} diff --git a/H09/src/main/java/h09/abilities/Swims.java b/H09/src/main/java/h09/abilities/Swims.java new file mode 100644 index 0000000..cbecbae --- /dev/null +++ b/H09/src/main/java/h09/abilities/Swims.java @@ -0,0 +1,36 @@ +package h09.abilities; + +/** + * An object of a class implementing {@link Swims} has the ability to swim and live in an {@link h09.WaterEnclosure} + */ +public interface Swims { + /** + * @return the elevation of the swimming animal + */ + float getElevation(); + + /** + * Lets the animal swim up and increase in elevation. + */ + void swimUp(); + + /** + * Lets the animal swim down and decrease in elevation. + */ + void swimDown(); + + /** + * The max elevation an animal can swim to. + */ + float MAX_ELEVATION = 0; + + /** + * The min elevation an animal can swim to. + */ + float MIN_ELEVATION = -10; + + /** + * The elevation above which an animal is considered at a high elevation or at the surface. + */ + float HIGH_ELEVATION = -3; +} diff --git a/H09/src/main/java/h09/abilities/Walks.java b/H09/src/main/java/h09/abilities/Walks.java new file mode 100644 index 0000000..9e62a9e --- /dev/null +++ b/H09/src/main/java/h09/abilities/Walks.java @@ -0,0 +1,11 @@ +package h09.abilities; + +/** + * An object of a class implementing {@link Walks} has the ability to walk and live in an {@link h09.GroundEnclosure} + */ +public interface Walks { + /** + * @return the number of legs of the animal + */ + int getNumberOfLegs(); +} diff --git a/H09/src/main/java/h09/animals/Animal.java b/H09/src/main/java/h09/animals/Animal.java new file mode 100644 index 0000000..29dde96 --- /dev/null +++ b/H09/src/main/java/h09/animals/Animal.java @@ -0,0 +1,71 @@ +package h09.animals; + +/** + * An object of a class {@link Animal} represents an animal. + */ +public class Animal { + /** + * Name of the animal. + */ + protected String name; + /** + * Age of the animal. + */ + private int age; + + /** + * A 'true' value represents that the animal is hungry. + */ + private boolean isHungry = true; + + /** + * Constructs an Animal with the given name and age. + * + * @param name the name of the animal + * @param age the age of the animal + */ + public Animal(String name, int age) { + this.name = name; + this.age = age; + } + + /** + * @return the name of the animal + */ + public String getName() { + return name; + } + + /** + * Lets the animal eat. This prints a message to the system output noting that the animal has eaten and sets the + * animal to not hungry. + */ + public void eat() { + System.out.println(name + " ate..."); + isHungry = false; + } + + /** + * Lets the animal sleep. This prints a message to the system output noting that the animal has eaten. It also + * increases the age of the animal and sets the animal to hungry. + */ + public void sleep() { + System.out.println(name + " slept..."); + isHungry = true; + age++; + } + + /** + * @return true if the animal is hungry; false otherwise + */ + public boolean isHungry() { + return isHungry; + } + + /** + * @return the age of the animal + */ + public int getAge() { + return age; + } +} diff --git a/H09/src/main/java/h09/animals/ClownFish.java b/H09/src/main/java/h09/animals/ClownFish.java new file mode 100644 index 0000000..f48abaa --- /dev/null +++ b/H09/src/main/java/h09/animals/ClownFish.java @@ -0,0 +1,14 @@ +package h09.animals; + +public class ClownFish extends Fish { + public ClownFish(String name, int age) { + super(name, age); + } + + /** + * Prints a joke about fish playing basketball. + */ + public void tellJoke() { + System.out.println(getName() + " says: Why don't fish play basketball? Because they're afraid of the net!"); + } +} diff --git a/H09/src/main/java/h09/animals/Fish.java b/H09/src/main/java/h09/animals/Fish.java new file mode 100644 index 0000000..ad3edca --- /dev/null +++ b/H09/src/main/java/h09/animals/Fish.java @@ -0,0 +1,34 @@ +package h09.animals; + +import h09.abilities.Swims; + +/** + * An object of a class {@link Fish} represents a fish which can swim. + */ +public class Fish extends Animal implements Swims { + /** + * Constructs a Fish with the given name and age. + * + * @param name the name of the animal + * @param age the age of the animal + */ + public Fish(String name, int age) { + super(name, age); + } + + @Override + public float getElevation() { + return Swims.MAX_ELEVATION - (Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (getName().length() + 1); + } + + @Override + public void swimUp() { + name += "Blub"; + } + + @Override + public void swimDown() { + if (name.length() < 4) return; + name = name.substring(0, name.length() - 4); + } +} diff --git a/H09/src/main/java/h09/animals/FlyingFish.java b/H09/src/main/java/h09/animals/FlyingFish.java new file mode 100644 index 0000000..a26f318 --- /dev/null +++ b/H09/src/main/java/h09/animals/FlyingFish.java @@ -0,0 +1,63 @@ +package h09.animals; + +import h09.abilities.Flies; +import h09.abilities.Swims; + +public class FlyingFish extends Animal implements Flies, Swims { + private boolean flying = false; + private float elevation = Swims.MIN_ELEVATION; + + /** + * Constructs an Animal with the given name and age. + * + * @param name the name of the animal + * @param age the age of the animal + */ + public FlyingFish(String name, int age) { + super(name, age); + } + + @Override + public void land() { + flying = false; + System.out.println(getName() + " landed with a splash!"); + + } + + @Override + public void takeOff() { + flying = true; + System.out.println(getName() + " took off and feels the wind in its face!"); + } + + @Override + public boolean isFlying() { + System.out.println(getName() + " enjoys flying!"); + return flying; + } + + + @Override + public float getElevation() { + return elevation; + } + + @Override + public void swimUp() { + elevation += 2; + if (elevation > Swims.MAX_ELEVATION) { + elevation = Swims.MAX_ELEVATION; + if (!flying) takeOff(); + } + } + + @Override + public void swimDown() { + if (flying) { + System.out.println(getName() + " can't swim down while flying!"); + return; + } + elevation -= 2; + if (elevation < Swims.MIN_ELEVATION) elevation = Swims.MIN_ELEVATION; + } +} diff --git a/H09/src/main/java/h09/animals/JugglingLion.java b/H09/src/main/java/h09/animals/JugglingLion.java new file mode 100644 index 0000000..3216f12 --- /dev/null +++ b/H09/src/main/java/h09/animals/JugglingLion.java @@ -0,0 +1,33 @@ +package h09.animals; + +public class JugglingLion extends Lion { + private int numberOfBalls; + private static final int MAX_BALLS = 7; + + public JugglingLion(String name, int age) { + super(name, age); + this.numberOfBalls = 3; // Default number of balls + } + + /** + * Prints a message that the lion is juggling. + */ + public void juggle() { + System.out.println(getName() + " is juggling " + numberOfBalls + " balls! What a talented lion!"); + if (numberOfBalls == MAX_BALLS) { + System.out.println("Wow! " + getName() + " is juggling the maximum number of balls!"); + } + if (numberOfBalls > MAX_BALLS) { + System.out.println("Oh no! " + getName() + " is dropping the balls!"); + numberOfBalls = 0; + } + } + + /** + * Increases the number of balls the lion is juggling. + */ + public void increaseBalls() { + numberOfBalls++; + System.out.println(getName() + " increased the number of balls to " + numberOfBalls + "!"); + } +} diff --git a/H09/src/main/java/h09/animals/KingPenguin.java b/H09/src/main/java/h09/animals/KingPenguin.java new file mode 100644 index 0000000..1b65e22 --- /dev/null +++ b/H09/src/main/java/h09/animals/KingPenguin.java @@ -0,0 +1,14 @@ +package h09.animals; + +public class KingPenguin extends Penguin { + public KingPenguin(String name, int age) { + super(name, age); + } + + /** + * Prints the name of the king penguin and that it is king. + */ + public void king() { + System.out.println(this.name + " is King!"); + } +} diff --git a/H09/src/main/java/h09/animals/Lion.java b/H09/src/main/java/h09/animals/Lion.java new file mode 100644 index 0000000..7633421 --- /dev/null +++ b/H09/src/main/java/h09/animals/Lion.java @@ -0,0 +1,23 @@ +package h09.animals; + +import h09.abilities.Walks; + +/** + * An object of a class {@link Lion} represents a lion which can walk. + */ +public class Lion extends Animal implements Walks { + /** + * Constructs a Lion with the given name and age. + * + * @param name the name of the animal + * @param age the age of the animal + */ + public Lion(String name, int age) { + super(name, age); + } + + @Override + public int getNumberOfLegs() { + return 4; + } +} diff --git a/H09/src/main/java/h09/animals/Penguin.java b/H09/src/main/java/h09/animals/Penguin.java new file mode 100644 index 0000000..f2e622f --- /dev/null +++ b/H09/src/main/java/h09/animals/Penguin.java @@ -0,0 +1,56 @@ +package h09.animals; + +import h09.abilities.Swims; +import h09.abilities.Walks; + +/** + * An object of a class {@link Penguin} represents a penguin which can swim and walk. + */ +public class Penguin extends Animal implements Walks, Swims { + float elevation = Swims.MAX_ELEVATION / Swims.MIN_ELEVATION; + + /** + * Constructs a Penguin with the given name and age. + * + * @param name the name of the animal + * @param age the age of the animal + */ + public Penguin(String name, int age) { + super(name, age); + } + + /** + * Constructs a Penguin with the given name, age and elevation. + * + * @param name the name of the animal + * @param age the age of the animal + * @param elevation the elevation of the animal + */ + public Penguin(String name, int age, float elevation) { + super(name, age); + this.elevation = elevation; + if (elevation > Swims.MAX_ELEVATION) this.elevation = Swims.MAX_ELEVATION; + if (elevation < Swims.MIN_ELEVATION) this.elevation = Swims.MIN_ELEVATION; + } + + @Override + public float getElevation() { + return elevation; + } + + @Override + public void swimUp() { + elevation = Swims.MAX_ELEVATION; + } + + @Override + public void swimDown() { + elevation -= 4; + if (elevation < Swims.MIN_ELEVATION) elevation = Swims.MIN_ELEVATION; + } + + @Override + public int getNumberOfLegs() { + return 2; + } +} diff --git a/H09/src/main/java/h09/animals/Turtle.java b/H09/src/main/java/h09/animals/Turtle.java new file mode 100644 index 0000000..fc420eb --- /dev/null +++ b/H09/src/main/java/h09/animals/Turtle.java @@ -0,0 +1,52 @@ +package h09.animals; + +import h09.abilities.Swims; +import h09.abilities.Walks; + +import java.util.Random; + +public class Turtle extends Animal implements Walks, Swims { + private float elevation = Swims.MAX_ELEVATION / Swims.MIN_ELEVATION; + private final Random random = new Random(); + + /** + * Constructs an Animal with the given name and age. + * + * @param name the name of the animal + * @param age the age of the animal + */ + public Turtle(String name, int age) { + super(name, age); + } + + + @Override + public float getElevation() { + return elevation; + } + + private void setElevation(float elevation) { + this.elevation = elevation; + if (elevation > Swims.MAX_ELEVATION) this.elevation = Swims.MAX_ELEVATION; + if (elevation < Swims.MIN_ELEVATION) this.elevation = Swims.MIN_ELEVATION; + } + + @Override + public void swimUp() { + float dElevation = (random.nextFloat()) * 2 - 0.5f; // Random float between -0.5 and 1.5 + if (dElevation < 0) System.out.println("Oh no! " + getName() + " is sinking!"); + setElevation(elevation + dElevation); + } + + @Override + public void swimDown() { + float dElevation = (random.nextFloat()) * 2 - 0.5f; // Random float between -0.5 and 1.5 + if (dElevation < 0) System.out.println("Oh no! " + getName() + " is floating up!"); + setElevation(elevation - dElevation); + } + + @Override + public int getNumberOfLegs() { + return 4; + } +} diff --git a/H09/src/test/java/h09/EnclosureTest.java b/H09/src/test/java/h09/EnclosureTest.java new file mode 100644 index 0000000..f6b5c2f --- /dev/null +++ b/H09/src/test/java/h09/EnclosureTest.java @@ -0,0 +1,25 @@ +package h09; + +import org.junit.jupiter.api.Test; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +/** + * An example JUnit test class. + */ +public class EnclosureTest { + + @Test + @StudentImplementationRequired("H9.5.1") + public void testForEach() { + // TODO: H9.5.1 + org.tudalgo.algoutils.student.Student.crash("H9.5.1 - Remove if implemented"); + } + + + @Test + @StudentImplementationRequired("H9.5.2") + public void testFilter() { + // TODO: H9.5.2 + org.tudalgo.algoutils.student.Student.crash("H9.5.2 - Remove if implemented"); + } +} diff --git a/H09/src/test/java/h09/ExampleJUnitTest.java b/H09/src/test/java/h09/ExampleJUnitTest.java new file mode 100644 index 0000000..7a72cf6 --- /dev/null +++ b/H09/src/test/java/h09/ExampleJUnitTest.java @@ -0,0 +1,74 @@ +package h09; + +import h09.abilities.Swims; +import h09.animals.Fish; +import h09.animals.Lion; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * An example JUnit test class. + */ +public class ExampleJUnitTest { + + @Test + public void testAddition() { + assertEquals(2, 1 + 1); + } + + @Test + public void testGroundEnclosure() { + // crating lions + Lion lia = new Lion("Lia", 1); + Lion lib = new Lion("Lib", 1); + Lion lic = new Lion("Lic", 1); + + // Creating lion enclosure... + GroundEnclosure lionEnclosure = new GroundEnclosure<>(); + lionEnclosure.getStack().push(lia); + lionEnclosure.getStack().push(lib); + lionEnclosure.getStack().push(lic); + + // Counting legs of lions... + assertEquals(3 * 4, lionEnclosure.countLegs()); + + // Feed the lions... + assertTrue(lia.isHungry()); + lionEnclosure.feed(); + assertFalse(lia.isHungry()); + } + + @Test + public void testWaterEnclosure() { + // crating fish + Fish fisha = new Fish("Fishaaa", 1); + Fish fib = new Fish("Fishbb", 1); + Fish fisch = new Fish("Fisch", 1); + + // Creating fish enclosure... + WaterEnclosure fishEnclosure = new WaterEnclosure<>(); + fishEnclosure.getStack().push(fisha); + fishEnclosure.getStack().push(fib); + fishEnclosure.getStack().push(fisch); + + // Check mean elevation / hungry + float expected1 = Swims.MAX_ELEVATION - + ((Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (fisha.getName().length() + 1) + + (Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (fib.getName().length() + 1) + + (Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (fisch.getName().length() + 1)) / 3; + assertEquals(expected1, fishEnclosure.getMeanElevation()); + assertTrue(fisch.isHungry()); + + // feed the fish (they swim down, when they have eaten) + fishEnclosure.feed(); + + // Check mean elevation / hungry + float expected2 = Swims.MAX_ELEVATION - + ((Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (fisha.getName().length() + 1) + + (Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (fib.getName().length() + 1) + + (Swims.MAX_ELEVATION - Swims.MIN_ELEVATION) / (fisch.getName().length() + 1)) / 3; + assertEquals(expected2, fishEnclosure.getMeanElevation()); + assertFalse(fisch.isHungry()); + } +} diff --git a/H09/src/test/java/h09/ExampleZooTest.java b/H09/src/test/java/h09/ExampleZooTest.java new file mode 100644 index 0000000..32f633f --- /dev/null +++ b/H09/src/test/java/h09/ExampleZooTest.java @@ -0,0 +1,66 @@ +package h09; + +import h09.animals.Animal; +import h09.animals.Fish; +import h09.animals.Penguin; +import org.junit.jupiter.api.Test; + +public class ExampleZooTest { + + @Test + public void runExampleZoo() { + // can be used after H9.2 + System.out.println("\nCreating fish enclosure..."); + WaterEnclosure fishEnclosure = new WaterEnclosure<>(); + fishEnclosure.getStack().push(new Fish("Fishaaa", 1)); + fishEnclosure.getStack().push(new Fish("Fishbb", 2)); + fishEnclosure.getStack().push(new Fish("Fisch", 3)); + + // can be used after H9.3.1 +// System.out.println("Get fish elevation..."); +// fishEnclosure.forEach(fish -> System.out.println(fish.getName() + ": " + fish.getElevation())); +// +// System.out.println("\nLet fish swim up..."); +// fishEnclosure.forEach(Fish::swimUp); +// fishEnclosure.forEach(Fish::swimUp); +// fishEnclosure.forEach(Fish::swimUp); + + System.out.println("\nFeed the fish..."); + fishEnclosure.feed(); + + System.out.println("\nGet fish mean elevation..."); + System.out.println("Mean elevation: " + fishEnclosure.getMeanElevation()); + + System.out.println("\nCreating penguin enclosure..."); + GroundEnclosure penguinGroundEnclosure = new GroundEnclosure<>(); + penguinGroundEnclosure.getStack().push(new Penguin("Penga", 5)); + penguinGroundEnclosure.getStack().push(new Penguin("Pengb", 10)); + penguinGroundEnclosure.getStack().push(new Penguin("Pengc", 10)); + penguinGroundEnclosure.getStack().push(new Penguin("Pengd", 30)); + penguinGroundEnclosure.getStack().push(new Penguin("Penge", 30)); + + System.out.println("\nMigrating the Penguins to a WaterEnclosure..."); +// WaterEnclosure penguinWaterEnclosure = new WaterEnclosure<>(); +// while (penguinGroundEnclosure.getStack().size() > 0) { +// Penguin penguin = penguinGroundEnclosure.getStack().pop(); +// penguinWaterEnclosure.getStack().push(penguin); +// } + + + // can be used after H9.3.2 +// System.out.println("\nRemoving old penguins..."); +// penguinWaterEnclosure.filterObj(Enclosure.IS_OLD.negate()); +// System.out.println(penguinWaterEnclosure.getStack().size() + " young penguin(s) left."); +// +// System.out.println("\nSleep /age again"); +// penguinWaterEnclosure.forEach(Animal::sleep); +// +// // can be used after H9.3.3 +// System.out.println("\nLooking for hungry and old Penguins..."); +// System.out.println(penguinWaterEnclosure.countHungry() + " hungry penguins."); +// System.out.println(penguinWaterEnclosure.filterFunc(WaterEnclosure::new, Enclosure.IS_OLD).getStack().size() + " old penguins."); +// +// System.out.println("\nFeed old penguins and let them sleep..."); +// penguinWaterEnclosure.filterFunc(WaterEnclosure::new, Enclosure.IS_OLD).forEach(Enclosure.FEED_AND_SLEEP); + } +} diff --git a/solution/H07/version b/H09/version similarity index 100% rename from solution/H07/version rename to H09/version diff --git a/H10/.editorconfig b/H10/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/H10/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/H10/.gitignore b/H10/.gitignore new file mode 100644 index 0000000..e3750f8 --- /dev/null +++ b/H10/.gitignore @@ -0,0 +1,86 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +jagr.conf diff --git a/H10/README.md b/H10/README.md new file mode 100644 index 0000000..7a5dbbc --- /dev/null +++ b/H10/README.md @@ -0,0 +1,4 @@ +# Vorlage zu Hausübung 10 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/H10/build.gradle.kts b/H10/build.gradle.kts new file mode 100644 index 0000000..cc1cf4c --- /dev/null +++ b/H10/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + alias(libs.plugins.algomate) +} + +exercise { + assignmentId.set("h10") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "" + firstName = "" + lastName = "" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h10.H10_RubricProviderPublic") + } + } +} diff --git a/H10/gradle/libs.versions.toml b/H10/gradle/libs.versions.toml new file mode 100644 index 0000000..46d58d4 --- /dev/null +++ b/H10/gradle/libs.versions.toml @@ -0,0 +1,2 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } diff --git a/H10/gradle/wrapper/gradle-wrapper.jar b/H10/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/H10/gradlew.bat b/H10/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/H10/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/H10/settings.gradle.kts b/H10/settings.gradle.kts new file mode 100644 index 0000000..202b342 --- /dev/null +++ b/H10/settings.gradle.kts @@ -0,0 +1,10 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + } +} + +rootProject.name = "H10-Student" diff --git a/H10/src/graderPublic/java/h10/CardGames.java b/H10/src/graderPublic/java/h10/CardGames.java new file mode 100644 index 0000000..1509911 --- /dev/null +++ b/H10/src/graderPublic/java/h10/CardGames.java @@ -0,0 +1,49 @@ +package h10; + +import h10.assertions.Links; +import h10.util.MockList; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; + +import java.util.List; + +/** + * Utility class for card games. + * + * @author Nhan Huynh + */ +public final class CardGames { + + /** + * Prevent instantiation of this utility class. + */ + private CardGames() { + } + + /** + * Creates a new card game from the given players and card deck. + * + * @param players the players to create the game with + * @param cardDeck the card deck to create the game with + * @return the new card game + */ + public static CardGame create(List players, List cardDeck) { + MyList playerList = new MockList<>(); + players.forEach(playerList::add); + MyList cardList = new MockList<>(); + cardDeck.forEach(cardList::add); + return new CardGame(playerList, cardList); + } + + /** + * Creates a new card game player. + * + * @param name the name of the player + * @return the new card game player + */ + public static CardGamePlayer createPlayer(String name) { + CardGamePlayer player = new CardGamePlayer(name); + FieldLink hand = Links.getField(CardGamePlayer.class, "hand"); + hand.set(player, new MockList<>()); + return player; + } +} diff --git a/H10/src/graderPublic/java/h10/DoublyLinkedLists.java b/H10/src/graderPublic/java/h10/DoublyLinkedLists.java new file mode 100644 index 0000000..1abc602 --- /dev/null +++ b/H10/src/graderPublic/java/h10/DoublyLinkedLists.java @@ -0,0 +1,35 @@ +package h10; + +import h10.util.ListItems; + +import java.util.List; + +/** + * Utility class for doubly linked lists. + * + * @author Nhan Huynh + */ +public final class DoublyLinkedLists { + + /** + * Prevent instantiation of this utility class. + */ + private DoublyLinkedLists() { + } + + /** + * Creates a new doubly linked list from the given elements. + * + * @param elements the elements to create the list from + * @param The type of the elements. + * @return the new doubly linked list from the given elements + */ + public static DoublyLinkedList create(List elements) { + ListItem head = ListItems.toItems(elements); + DoublyLinkedList list = new DoublyLinkedList<>(); + list.head = head; + list.tail = ListItems.itemStream(head).reduce((a, b) -> b).orElse(null); + list.size = elements.size(); + return list; + } +} diff --git a/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java new file mode 100644 index 0000000..8c97b70 --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java @@ -0,0 +1,88 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonConverters; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.1.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.1 | Liste von Spielern erstellen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_1_TestsPublic extends H10_Tests { + + /** + * The converters for the JSON parameters. + */ + public static final Map> CONVERTERS = Map.of( + "names", node -> JsonConverters.toList(node, JsonNode::asText) + ); + + @Override + public Class getClassType() { + return ListItemExamples.class; + } + + @Override + public String getMethodName() { + return "createPlayerListFromNames"; + } + + @Override + public List> getMethodParameters() { + return List.of(String[].class); + } + + @DisplayName("Die Liste wird korrekt erstellt und zurückgegeben. Jedes Listenelement verweist korrekt auf den vorherigen und nächsten Spieler, sofern dieser existiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_1_1.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) { + List expected = parameters.get("names"); + Context context = contextBuilder() + .add("names", expected.toString()) + .add("Expected list", expected.toString()) + .build(); + + // Method to test + ListItem actual = ListItemExamples.createPlayerListFromNames(expected.toArray(String[]::new)); + + // Check order of elements + TutorAssertions.assertEquals(expected, actual, CardGamePlayer::getName, context); + + // Check references + Iterator expectedIterator = expected.iterator(); + Iterator> playerIterator = ListItems.itemIterator(actual); + ListItem previous = null; + while (expectedIterator.hasNext() && playerIterator.hasNext()) { + expectedIterator.next(); + ListItem actualPlayer = playerIterator.next(); + + if (previous != null) { + ListItem currentPrevious = previous; + Assertions2.assertEquals(previous.next.key.getName(), actualPlayer.key.getName(), context, + result -> "The next player of %s should be %s." + .formatted(currentPrevious.key.getName(), actualPlayer.key.getName())); + } + previous = actualPlayer; + } + } +} diff --git a/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java new file mode 100644 index 0000000..f82d0fd --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java @@ -0,0 +1,48 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.1.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.3 | Vorkommen der Karte SKIP zählen - mit Iterator") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_4_TestsPublic extends H10_1_CountSkipCards_Tests { + + public static final Map> CONVERTERS = Map.of( + "deck", node -> JsonConverters.toList(node, JsonConverters::toPlayingCard), + "skips", JsonNode::asInt + ); + + @Override + protected String getImplementationType() { + return "Iterator"; + } + + @Override + public List> getMethodParameters() { + return List.of(List.class); + } + + @DisplayName("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.") + @Override + @ParameterizedTest + @JsonParameterSetTest(value = "H10_1_CountSkipCards.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) throws Throwable { + assertResult(parameters); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java b/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java new file mode 100644 index 0000000..cf35709 --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java @@ -0,0 +1,90 @@ +package h10; + +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.Assertions; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +/** + * Defines the tests for {@code countSkipCardsXYZ} in the class {@code ListItemExamples}. + * + *

The class which implements this abstract class should override the method {@code testResult} and annotate it + * with the {@code @ParameterizedTest} and {@code @JsonParameterSetTest} annotations. + * + *

Use the following schema: + *

{@code
+ *      public class XYZ_Tests extends H10_1_CountSkipCards_Tests {
+ *
+ *          public static final Map> CONVERTERS = Map.of(
+ *              "deck", node -> ...,
+ *               "skips", JsonNode::asInt
+ *          );
+ *
+ *         protected abstract String getImplementationType() {
+ *          return ...; // "Recursive" or "Iterative" or "Iterator"
+ *         }
+ *
+ *         @ParameterizedTest
+ *         @JsonParameterSetTest(value = "H10_1_CountSkipCards.json", customConverters = CUSTOM_CONVERTERS)
+ *         @Override
+ *         void testResult(JsonParameterSet parameters) throws Throwable {
+ *         super.testResult(parameters);
+ *         }
+ *      }
+ *  }
+ * + * @author Nhan Huynh + */ +public abstract class H10_1_CountSkipCards_Tests extends H10_Tests { + + + @Override + public Class getClassType() { + return ListItemExamples.class; + } + + /** + * Returns the implementation type for the method to test which is either recursive or iterative or using + * iterators. + * + * @return the implementation type for the method to test + */ + protected abstract String getImplementationType(); + + @Override + public String getMethodName() { + if (!getImplementationType().equals("Recursive") + && !getImplementationType().equals("Iterative") + && !getImplementationType().equals("Iterator") + ) { + Assertions.fail("The implementation type must be either Recursive or Iterative or Iterator."); + } + + return "countSkipCards" + getImplementationType(); + } + + /** + * Asserts the result of the method. + * @param parameters the parameters for the test method + * @throws Throwable if an error occurs + */ + void assertResult(JsonParameterSet parameters) throws Throwable { + Object deck = parameters.get("deck"); + int expectedSkips = parameters.get("skips"); + Context context = contextBuilder() + .add("Deck", (deck instanceof ListItem items ? ListItems.stream(items).toList() : deck).toString()) + .add("Expected number of skips", expectedSkips) + .build(); + + MethodLink method = getMethod(); + int actualSkips = method.invokeStatic(deck); + + Assertions2.assertEquals(expectedSkips, actualSkips, context, + result -> "The number of SKIP cards in the deck is incorrect."); + } + + abstract void testResult(JsonParameterSet parameters) throws Throwable; +} diff --git a/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java new file mode 100644 index 0000000..5dec7c9 --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java @@ -0,0 +1,65 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.1 | Ist dieses Element bereits in der Liste?") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_1_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "list", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "key", JsonNode::asInt, + "index", JsonNode::asInt + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "findFirstHelper"; + } + + @Override + public List> getMethodParameters() { + return List.of(ListItem.class, Object.class, int.class); + } + + @DisplayName("Die Methode gibt den Index des ersten Vorkommens des Elements zurück, falls es in der Liste enthalten ist. Andernfalls wird -1 zurückgegeben.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_1.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("list"); + int key = parameters.get("key"); + int index = parameters.get("index"); + Context context = contextBuilder() + .add("List", list.toString()) + .add("Key", key) + .add("Expected index", index) + .build(); + int actual = list.findFirst(key); + Assertions2.assertEquals(index, actual, context, result -> "Index of first occurrence mismatch."); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java new file mode 100644 index 0000000..9aaedbe --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java @@ -0,0 +1,66 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.2 | Auf ein Element in der Liste zugreifen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_2_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "index", JsonNode::asInt, + "element", JsonNode::asInt, + "searchFromStart", JsonNode::asBoolean + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "getListItem"; + } + + @Override + public List> getMethodParameters() { + return List.of(int.class); + } + + @DisplayName("Die Methode gibt das Element an der angegebenen Position zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_2_Position.json", customConverters = CUSTOM_CONVERTERS) + void testPositions(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + int element = parameters.get("element"); + Context context = contextBuilder() + .add("List", list.toString()) + .add("Index", index) + .add("Element to get", element) + .build(); + int actual = list.get(index); + Assertions2.assertEquals(element, actual, context, result -> "Element at the index %s mismatch".formatted(index)); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java new file mode 100644 index 0000000..8514f5d --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java @@ -0,0 +1,126 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.3 | Ein Element hinzufügen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_3_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "index", JsonNode::asInt, + "key", JsonNode::asInt, + "expected", node -> JsonConverters.toList(node, JsonNode::asInt), + "size", JsonNode::asInt + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "add"; + } + + @Override + public List> getMethodParameters() { + return List.of(int.class, Object.class); + } + + @DisplayName("Fall 1: Die Liste ist leer wurde korrekt implementiert.") + @Test + void testEmptyList() { + DoublyLinkedList list = new DoublyLinkedList<>(); + int element = 1; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to add", element) + .add("Expected list after adding", List.of(element)) + .build(); + list.add(element); + + Assertions2.assertEquals(1, list.head.key, context, result -> "Head key mismatch."); + Assertions2.assertEquals(1, list.tail.key, context, result -> "Tail key mismatch."); + Assertions2.assertSame(list.head, list.tail, context, result -> "Head and tail should be the same."); + Assertions2.assertNull(list.head.prev, context, result -> "Head prev should be null."); + Assertions2.assertNull(list.head.next, context, result -> "Tail next should be null."); + } + + @DisplayName("Fall 3: Neues Element an den Anfang der Liste wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Start.json", customConverters = CUSTOM_CONVERTERS) + void testStart(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int element = parameters.get("key"); + List expected = parameters.get("expected"); + int index = 0; + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .add("Expected list after adding", expected.toString()) + .build(); + + list.add(index, element); + + // Check elements + TutorAssertions.assertEquals(expected, list.head, context); + + // Check references + Assertions2.assertSame(list.head.next, items.getFirst(), context, result -> "Head next mismatch."); + Assertions2.assertNull(list.head.prev, context, result -> "Head does not have a previous item."); + Assertions2.assertSame(items.getFirst().prev, list.head, context, + result -> "The successor of the head does not have the head as the previous item."); + } + + @DisplayName("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Exception.json", customConverters = CUSTOM_CONVERTERS) + void testIndexOutOfBoundsException(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + int element = parameters.get("key"); + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .build(); + + Assertions2.assertThrows( + IndexOutOfBoundsException.class, + () -> list.add(index, element), + context, + result -> "List with size %s should throw an index out of bounds exception for index %s." + .formatted(list.size, index) + ); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java new file mode 100644 index 0000000..f329c9a --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java @@ -0,0 +1,130 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.4 | Ein Element entfernen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_4_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = new HashMap<>( + Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "element", JsonNode::asInt, + "expected", node -> JsonConverters.toList(node, JsonNode::asInt), + "size", JsonNode::asInt + ) + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "removeListItem"; + } + + @Override + public List> getMethodParameters() { + return List.of(ListItem.class); + } + + @DisplayName("Der Fall 1 wurde korrekt implementiert.") + @Test + void testCase1() throws Throwable { + ListItem item = new ListItem<>(1); + DoublyLinkedList list = new DoublyLinkedList<>(); + list.head = item; + list.tail = item; + list.size = 1; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", item) + .add("Expected list after removal", List.of()) + .build(); + + int removed = getMethod().invoke(list, item); + + Assertions2.assertEquals(item.key, removed, context, + result -> "Returned value should be the key of the removed item"); + Assertions2.assertNull(list.head, context, result -> "Head should be null"); + Assertions2.assertNull(list.tail, context, result -> "Tail should be null"); + } + + @DisplayName("Der Fall 4 wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_Case4.json", customConverters = CUSTOM_CONVERTERS) + void testCase4(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int key = parameters.get("key"); + ListItem toRemove = items.stream().filter(item -> item.key.equals(key)).findFirst().orElseThrow(); + ListItem prev = toRemove.prev; + ListItem next = toRemove.next; + List expected = parameters.get("expected"); + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", toRemove) + .add("Expected list after removal", expected.toString()) + .build(); + + int removed = getMethod().invoke(list, toRemove); + Assertions2.assertEquals(toRemove.key, removed, context, + result -> "Returned value should be the key of the removed item"); + TutorAssertions.assertEquals(expected, list.head, context); + + // Check references + Assertions2.assertSame(next, prev.next, context, result -> "removed.next != removed.prev.next"); + Assertions2.assertSame(prev, next.prev, context, result -> "removed.prev != removed.next.prev"); + } + + @DisplayName("Das entfernte Element verweist immernoch auf seine Nachbarn.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_References.json", customConverters = CUSTOM_CONVERTERS) + void testReference(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int key = parameters.get("key"); + ListItem toRemove = items.stream().filter(item -> item.key.equals(key)).findFirst().orElseThrow(); + ListItem prev = toRemove.prev; + ListItem next = toRemove.next; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", toRemove) + .build(); + + getMethod().invoke(list, toRemove); + + // Check references + Assertions2.assertSame(prev, toRemove.prev, context, result -> "removed.prev != removed.prev"); + Assertions2.assertSame(next, toRemove.next, context, result -> "removed.next != removed.next"); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java new file mode 100644 index 0000000..048d20f --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java @@ -0,0 +1,66 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.5. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.5 | Alle Elemente entfernen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_5_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt) + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "clear"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + @DisplayName("Nach einem Aufruf von clear() ist die Liste leer. Insbesondere sind head und tail auf null gesetzt, und die Größe der Liste ist 0.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_5.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Expected list after clear()", List.of()) + .add("Expected size after clear()", 0) + .build(); + + list.clear(); + + Assertions2.assertNull(list.head, context, result -> "Head should be null after clear()"); + Assertions2.assertNull(list.tail, context, result -> "Tail should be null after clear()"); + Assertions2.assertEquals(0, list.size(), context, result -> "Size should be 0 after clear()"); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java new file mode 100644 index 0000000..2520181 --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java @@ -0,0 +1,156 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; + +/** + * Defines the public tests for H10.3.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.1 | Das nächste Element zurückgeben") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_1_TestsPublic extends H10_Tests { + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "cyclicIterator"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + @DisplayName("Die Methode hasNext() gibt korrekt an, ob es ein nächstes Element gibt.") + @Test + void testHasNext() { + List> testCases = List.of( + List.of(1, 2, 3), + List.of(1), + List.of() + ); + testCases.forEach(elements -> { + DoublyLinkedList list = DoublyLinkedLists.create(elements); + BidirectionalIterator it = list.cyclicIterator(); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", elements.isEmpty() ? "No elements left" : "null") + .add("Next element", elements.isEmpty() ? "No elements left" : elements.getFirst()) + .build(); + + if (elements.isEmpty()) { + Assertions2.assertFalse(it.hasNext(), context, + result -> "hasNext() should return false if there are no elements left."); + } else { + Assertions2.assertTrue(it.hasNext(), context, + result -> "hasNext() should return true if there are elements left."); + } + }); + } + + @DisplayName("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextEmpty() { + List elements = List.of(1, 2, 3); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", "null") + .add("Next element", elements.getFirst()) + .build(); + + Assertions2.assertEquals(elements.getFirst(), it.next(), context, + result -> "next() should return the first element of the list."); + Assertions2.assertEquals(items, it.p, context, result -> "p should point to the first element of the list."); + } + + @DisplayName("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextEnd() { + List elements = List.of(1, 2, 3); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + List> refs = ListItems.itemStream(items).toList(); + + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + it.p = refs.getLast(); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", elements.getLast()) + .add("Next element", elements.getFirst()) + .build(); + + Assertions2.assertEquals(elements.getFirst(), it.next(), context, + result -> "next() should return the first element of the list."); + Assertions2.assertEquals(items, it.p, context, result -> "p should point to the first element of the list."); + } + + @DisplayName("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextMiddle() { + List elements = List.of(1, 2, 3, 4, 5); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + List> refs = ListItems.itemStream(items).toList(); + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + int start = 1; + int end = elements.size() - 1; + for (int i = start; i < end; i++) { + it.p = refs.get(i - 1); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", elements.get(i - 1)) + .add("Next element", elements.get(i)) + .build(); + + int currentIndex = i; + Assertions2.assertEquals(elements.get(i), it.next(), context, + result -> "next() result mismatch at index %s.".formatted(currentIndex)); + Assertions2.assertEquals(refs.get(i), it.p, context, + result -> "p reference mismatch at index %s.".formatted(currentIndex)); + } + } + + @DisplayName("Die Methode next() setzt das Attribut calledRemove auf false.") + @Test + void testCalledRemove() { + List elements = List.of(1, 2, 3, 4, 5); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + it.p = items; + it.calledRemove = true; + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", elements.getFirst()) + .add("Next element", elements.get(1)) + .add("calledRemove", true) + .build(); + + Assertions2.call(it::next, context, result -> "Expected next() to be called without exception."); + Assertions2.assertFalse(it.calledRemove, context, result -> "calledRemove should be set to false after call."); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java b/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java new file mode 100644 index 0000000..a59a6c2 --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java @@ -0,0 +1,206 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.ArrayList; +import java.util.List; + +/** + * Defines the public tests for H10.3.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.3 | Verlierer des Spiels bestimmen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_3_TestsPublic extends H10_Tests { + + @Override + public Class getClassType() { + return CardGame.class; + } + + @Override + public String getMethodName() { + return "doTurn"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + /** + * Converts a MyList to a List. + * + * @param myList the MyList to convert + * @param the type of the elements in the list. + * + * @return the converted List. + */ + protected List fromMyList(MyList myList) { + List list = new ArrayList<>(); + for (int i = 0; i < myList.size(); i++) { + list.add(myList.get(i)); + } + return list; + } + + @DisplayName("Bei einem SKIP wird der nächste Spieler übersprungen.") + @Test + void testSkip() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.SKIP); + playerOne.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.SKIP); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + + CardGame game = CardGames.create(players, deck); + + int nextHandSize = playerTwo.getHandSize(); + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerTwo) + .add("Playing card", PlayingCard.SKIP) + .build(); + + // Current player turn + getMethod().invoke(game); + // Check if skip is correctly set + Assertions2.assertTrue(game.skipNextPlayer, context, result -> "The game should skip the next player."); + + // Next player turn + getMethod().invoke(game); + + // Check if the next player is skipped + Assertions2.assertSame(playerTwo, game.currentPlayer, context, + result -> "The current player should be the next player."); + + Assertions2.assertFalse(game.skipNextPlayer, context, + result -> "Skip player should be reset after skipping the next player."); + Assertions2.assertEquals(nextHandSize, playerTwo.getHandSize(), context, + result -> "The next player should not play any cards."); + } + + @DisplayName("Bei einer REVERSE-Karte wird die Richtung des Iterators umgekehrt.") + @Test + void testReverse() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.REVERSE); + playerOne.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.SKIP); + + playerFour.takeCard(PlayingCard.SKIP); + playerFour.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.SKIP); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList).flatMap(List::stream). + toList(); + CardGame game = CardGames.create(players, deck); + + int successorPlayerHandSize = playerTwo.getHandSize(); + int predecessorPlayerHandSize = playerFour.getHandSize(); + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerFour) + .add("Playing card", PlayingCard.REVERSE) + .build(); + + // Current player turn + getMethod().invoke(game); + + // Check if skip is correctly set + Assertions2.assertTrue(game.reverseDirection, context, result -> "The game should reverse the direction."); + + // Last player turn + getMethod().invoke(game); + Assertions2.assertSame(playerFour, game.currentPlayer, context, + result -> "The current player should be the last player."); + Assertions2.assertEquals(successorPlayerHandSize, playerTwo.getHandSize(), context, + result -> "The last player should not play any card."); + Assertions2.assertEquals(predecessorPlayerHandSize - 1, playerFour.getHandSize(), context, + result -> "The last player should play one card."); + } + + @DisplayName("Spieler, die keine Karten mehr auf der Hand haben, werden aus dem Spiel entfernt.") + @Test + void testNoCards() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + }); + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + CardGame game = CardGames.create(players, deck); + + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Playing card", PlayingCard.PASS) + .build(); + + int numberOfPlayers = players.size(); + // Current player turn + getMethod().invoke(game); + Assertions2.assertEquals(0, playerOne.getHandSize(), context, result -> "The player should not have any card."); + Assertions2.assertEquals(numberOfPlayers - 1, game.players.size(), + context, result -> "The player should be removed from the game."); + } +} diff --git a/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java b/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java new file mode 100644 index 0000000..91bf00d --- /dev/null +++ b/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java @@ -0,0 +1,18 @@ +package h10; + +import h10.rubric.H10_RubricProvider; + +/** + * A public rubric provider for H10. + * + * @author Nhan Huynh + */ +public class H10_RubricProviderPublic extends H10_RubricProvider { + + /** + * Constructs a new public rubric provider. + */ + public H10_RubricProviderPublic() { + super(true); + } +} diff --git a/H10/src/graderPublic/java/h10/JsonConverters.java b/H10/src/graderPublic/java/h10/JsonConverters.java new file mode 100644 index 0000000..641f8c0 --- /dev/null +++ b/H10/src/graderPublic/java/h10/JsonConverters.java @@ -0,0 +1,107 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.Links; +import h10.util.ListItems; +import h10.util.MockList; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +/** + * Utility class for working with JSON data. + * + * @author Nhan Huynh + */ +public final class JsonConverters extends org.tudalgo.algoutils.tutor.general.json.JsonConverters { + + /** + * Prevent instantiation of this utility class. + */ + private JsonConverters() { + } + + /** + * Converts the given JSON node to a list of items using the given mapper. + * + * @param node the JSON node to convert + * @param mapper the mapper to use for mapping the items + * @param the type of the items in the list + * @return the head of the list item created from the JSON node + */ + public static ListItem toItems(JsonNode node, Function mapper) { + if (!node.isArray()) { + throw new IllegalArgumentException("Node is not an array"); + } + return ListItems.toItems(toList(node, mapper)); + } + + /** + * Converts the given JSON node to a playing card. + * + * @param node the JSON node to convert + * @return the playing card represented by the JSON node + */ + public static PlayingCard toPlayingCard(JsonNode node) { + if (!node.isTextual()) { + throw new IllegalArgumentException("Node is not a textual"); + } + String value = node.asText().toUpperCase(); + return Arrays.stream(PlayingCard.values()).filter(card -> card.name().equals(value)).findFirst().orElseThrow(); + } + + /** + * Converts the given JSON node to a deck of playing cards. + * + * @param node the JSON node to convert + * @return the deck of playing cards represented by the JSON node + */ + public static List toDeck(JsonNode node) { + if (!node.isArray()) { + throw new IllegalArgumentException("Node is not an array"); + } + return toList(node, JsonConverters::toPlayingCard); + } + + /** + * Converts the given JSON node to a player. + * + * @param node the JSON node to convert + * @return the player represented by the JSON node + */ + public static CardGamePlayer toPlayer(JsonNode node) { + if (!node.isObject()) { + throw new IllegalArgumentException("Node is not an object"); + } + CardGamePlayer player = new CardGamePlayer(node.get("name").asText()); + FieldLink hand = Links.getField(CardGamePlayer.class, "hand"); + hand.set(player, MockList.of(toList(node.get("hand"), JsonConverters::toPlayingCard))); + return player; + } + + /** + * Converts the given JSON node to a doubly linked list. + * + * @param node the JSON node to convert + * @param mapper the mapper to use for mapping the items + * @param the type of the items in the list + * @return the doubly linked list represented by the JSON nodeo + */ + public static DoublyLinkedList toDoublyLinkedList(JsonNode node, Function mapper) { + if (!node.isArray()) { + throw new IllegalArgumentException("Node is not an array"); + } + DoublyLinkedList list = new DoublyLinkedList<>(); + list.head = toItems(node, mapper); + list.tail = list.head; + int size = 0; + for (ListItem current = list.head; current != null; current = current.next) { + list.tail = current; + size++; + } + list.size = size; + return list; + } +} diff --git a/H10/src/graderPublic/java/h10/assertions/Links.java b/H10/src/graderPublic/java/h10/assertions/Links.java new file mode 100644 index 0000000..cfeb5a9 --- /dev/null +++ b/H10/src/graderPublic/java/h10/assertions/Links.java @@ -0,0 +1,109 @@ +package h10.assertions; + +import org.tudalgo.algoutils.tutor.general.assertions.Assertions3; +import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.match.MatcherFactories; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.PackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; + +/** + * Utility class for links to classes and methods. + * + * @author Nhan Huynh + */ +public final class Links { + + /** + * Matcher factory for string matchers. + */ + private static final MatcherFactories.StringMatcherFactory STRING_MATCHER_FACTORY = BasicStringMatchers::identical; + + /** + * The package link for the h10 package. + */ + public static final PackageLink PACKAGE = BasicPackageLink.of("h10"); + + /** + * Prevent instantiation of this utility class. + */ + private Links() { + + } + + /** + * Returns the type link for the given class. + * + * @param clazz the class to get the type from + * @return the type link for the given class + */ + public static TypeLink getType(Class clazz) { + return Assertions3.assertTypeExists( + PACKAGE, + STRING_MATCHER_FACTORY.matcher(clazz.getSimpleName()) + ); + } + + /** + * Returns the field link for the given type and field name. + * + * @param type the type to get the field from + * @param methodName the name of the field + * @param matchers the matchers for additional checks to retrieve the field + * @return the field link for the given type and field name + */ + @SafeVarargs + public static FieldLink getField(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertFieldExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the field link for the given class and field name. + * + * @param clazz the class to get the field from + * @param fieldName the name of the field + * @param matchers the matchers for additional checks to retrieve the field + * @return the field link for the given class and field name + */ + @SafeVarargs + public static FieldLink getField(Class clazz, String fieldName, Matcher... matchers) { + return getField(getType(clazz), fieldName, matchers); + } + + /** + * Returns the method link for the given type and method name. + * + * @param type the type to get the method from + * @param methodName the name of the method + * @param matchers the matchers for additional checks to retrieve the method + * @return the method link for the given type and method name + */ + @SafeVarargs + public static MethodLink getMethod(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertMethodExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the method link for the given class and method name. + * + * @param clazz the class to get the method from + * @param methodName the name of the method + * @param matchers the matchers for additional checks to retrieve the method + * @return the method link for the given class and method name + */ + @SafeVarargs + public static MethodLink getMethod(Class clazz, String methodName, Matcher... matchers) { + return getMethod(getType(clazz), methodName, matchers); + } +} diff --git a/H10/src/graderPublic/java/h10/assertions/TestConstants.java b/H10/src/graderPublic/java/h10/assertions/TestConstants.java new file mode 100644 index 0000000..6e29843 --- /dev/null +++ b/H10/src/graderPublic/java/h10/assertions/TestConstants.java @@ -0,0 +1,26 @@ +package h10.assertions; + +/** + * Constants for tests for configuring test behavior. + * + * @author Nhan Huynh + */ +public final class TestConstants { + + + /** + * Timeout for tests in seconds. + */ + public static final int TEST_TIMEOUT_IN_SECONDS = 2; + + /** + * Skip after first failed test. + */ + public static final boolean SKIP_AFTER_FIRST_FAILED_TEST = true; + + /** + * Prevent instantiation of this utility class. + */ + private TestConstants() { + } +} diff --git a/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java b/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java new file mode 100644 index 0000000..30100a0 --- /dev/null +++ b/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java @@ -0,0 +1,89 @@ +package h10.assertions; + +import h10.ListItem; +import h10.util.ListItems; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.Iterator; +import java.util.function.Function; + +/** + * Defines tutor-specific assertions for the h10 package. + * + * @author Nhan Huynh + */ +public final class TutorAssertions { + + /** + * Prevent instantiation of this utility class. + */ + private TutorAssertions() { + } + + + /** + * Asserts that the given expected elements are equal to the actual elements. + * + * @param expected the expected elements + * @param actual the actual elements + * @param mapper the mapper to convert the actual elements to the expected elements + * @param context the context to use for the assertions + * @param the type of the elements + */ + public static void assertEquals(Iterable expected, ListItem actual, Function mapper, Context context) { + assertEquals(expected, () -> ListItems.stream(actual).map(mapper).map(it -> (Object) it).iterator(), context); + } + + /** + * Asserts that the given expected elements are equal to the actual elements. + * + * @param expected the expected elements + * @param actual the actual elements + * @param context the context to use for the assertions + */ + public static void assertEquals(Iterable expected, ListItem actual, Context context) { + assertEquals(expected, actual, Function.identity(), context); + } + + /** + * Asserts that the given expected elements are equal to the actual elements. + * + * @param expected the expected elements + * @param actual the actual elements + * @param context the context to use for the assertions + */ + public static void assertEquals(Iterable expected, Iterable actual, Context context) { + Iterator itE = expected.iterator(); + Iterator itA = actual.iterator(); + int index = 0; + while (itE.hasNext() && itA.hasNext()) { + int currentIndex = index; + Assertions2.assertEquals(itE.next(), itA.next(), context, + result -> "Element at index " + currentIndex + " does not match"); + index++; + } + + // Check if expected or actual contains more elements + int overflow = 0; + while (itE.hasNext()) { + itE.next(); + overflow++; + } + + if (overflow > 0) { + int currentOverflow = overflow; + Assertions2.fail(context, + result -> "Actual list has %s fewer elements".formatted(currentOverflow)); + } + while (itA.hasNext()) { + itA.next(); + overflow++; + } + if (overflow > 0) { + int currentOverflow = overflow; + Assertions2.fail(context, + result -> "Actual list has %s more elements".formatted(currentOverflow)); + } + } +} diff --git a/H10/src/graderPublic/java/h10/rubric/Builder.java b/H10/src/graderPublic/java/h10/rubric/Builder.java new file mode 100644 index 0000000..df0db38 --- /dev/null +++ b/H10/src/graderPublic/java/h10/rubric/Builder.java @@ -0,0 +1,16 @@ +package h10.rubric; + +/** + * A builder interface for building objects. + * + * @param the type of object to build + */ +public interface Builder { + + /** + * Builds the object. + * + * @return the built object + */ + T build(); +} diff --git a/H10/src/graderPublic/java/h10/rubric/Criteriable.java b/H10/src/graderPublic/java/h10/rubric/Criteriable.java new file mode 100644 index 0000000..67165a4 --- /dev/null +++ b/H10/src/graderPublic/java/h10/rubric/Criteriable.java @@ -0,0 +1,19 @@ +package h10.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; + +/** + * An object that implements this interface indicates that it can be converted to a {@link Criterion} which means + * it is gradable. + * + * @author Nhan Huynh + */ +public interface Criteriable { + + /** + * Returns the criterion that represents this object. + * + * @return the criterion that represents this object + */ + Criterion getCriterion(); +} diff --git a/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java b/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java new file mode 100644 index 0000000..32ef4a8 --- /dev/null +++ b/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java @@ -0,0 +1,238 @@ +package h10.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Provides the rubric for H10. + * + * @author Nhan Huynh + */ +public abstract class H10_RubricProvider implements RubricProvider { + + /** + * Defines the subtask H10.1.1 for task H10.1. + */ + private static final Subtask H10_1_1 = Subtask.builder() + .description("H10.1.1 | Liste von Spielern erstellen") + .testClassName("h10.H10_1_1_Tests") + .criterion("Die Liste wird korrekt erstellt und zurückgegeben. Jedes Listenelement verweist korrekt auf den vorherigen und nächsten Spieler, sofern dieser existiert.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.1.2 for task H10.1. + */ + private static final Subtask H10_1_2 = Subtask.builder() + .description("H10.1.2 | Vorkommen der Karte SKIP zählen - iterativ") + .testClassName("h10.H10_1_2_Tests") + .criterion("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.", false, "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion", "testLoops") + .build(); + + /** + * Defines the subtask H10.1.3 for task H10.1. + */ + private static final Subtask H10_1_3 = Subtask.builder() + .description("H10.1.3 | Vorkommen der Karte SKIP zählen - rekursiv") + .testClassName("h10.H10_1_3_Tests") + .criterion("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.", false, "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Schleifen", "testRecursions") + .build(); + + /** + * Defines the subtask H10.1.4 for task H10.1. + */ + private static final Subtask H10_1_4 = Subtask.builder() + .description("H10.1.4 | Vorkommen der Karte SKIP zählen - mit Iterator") + .testClassName("h10.H10_1_4_Tests") + .criterion("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion", "testLoops") + .build(); + + /** + * Defines the task H10.1. + */ + private static final Task H10_1 = Task.builder() + .description("H10.1 | Beispiele mit Klasse ListItem") + .subtasks(H10_1_1, H10_1_2, H10_1_3, H10_1_4) + .build(); + + + /** + * Defines the subtask H10.2.1 for task H10.2. + */ + private static final Subtask H10_2_1 = Subtask.builder() + .description("H10.2.1 | Ist dieses Element bereits in der Liste?") + .testClassName("h10.H10_2_1_Tests") + .criterion("Die Methode gibt den Index des ersten Vorkommens des Elements zurück, falls es in der Liste enthalten ist. Andernfalls wird -1 zurückgegeben.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Schleifen", "testRecursions") + .build(); + + /** + * Defines the subtask H10.2.2 for task H10.2. + */ + private static final Subtask H10_2_2 = Subtask.builder() + .description("H10.2.2 | Auf ein Element in der Liste zugreifen") + .testClassName("h10.H10_2_2_Tests") + .criterion("Die Methode gibt das Element an der angegebenen Position zurück.", "testPositions", JsonParameterSet.class) + .criterion("Die Suche wird in der Liste von vorne oder hinten gestartet, je nachdem, welcher Weg kürzer ist.", false, "testPath", JsonParameterSet.class) + .criterion("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.", false, "testException", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion", "testLoops") + .build(); + + /** + * Defines the subtask H10.2.3 for task H10.2. + */ + private static final Subtask H10_2_3 = Subtask.builder() + .description("H10.2.3 | Ein Element hinzufügen") + .testClassName("h10.H10_2_3_Tests") + .criterion("Fall 1: Die Liste ist leer wurde korrekt implementiert.", "testEmptyList") + .criterion("Fall 2: Neues Element an das Ende der Liste wurde korrekt implementiert.", false, "testEnd", JsonParameterSet.class) + .criterion("Fall 3: Neues Element an den Anfang der Liste wurde korrekt implementiert.", "testStart", JsonParameterSet.class) + .criterion("Fall 4: Neues Element in der Mitte der Liste wurde korrekt implementiert.", false, "testMiddle", JsonParameterSet.class) + .criterion("Die Größe der Liste wird um 1 erhöht.", false, "testSize", JsonParameterSet.class) + .criterion("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.", "testIndexOutOfBoundsException", JsonParameterSet.class) + .criterion("Falls der übergebene key null ist, wird eine IllegalArgumentException geworfen.", false, "testIllegalArgumentException", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.2.4 for task H10.2. + */ + private static final Subtask H10_2_4 = Subtask.builder() + .description("H10.2.4 | Ein Element entfernen") + .testClassName("h10.H10_2_4_Tests") + .criterion("Die Fälle 1 und 4 wurden korrekt implementiert.", Map.of( + "testCase1", List.of(), + "testCase4", List.of(JsonParameterSet.class) + )) + .criterion("Die Fälle 2 und 3 wurden korrekt implementiert.", false, Map.of( + "testCase2", List.of(JsonParameterSet.class), + "testCase3", List.of(JsonParameterSet.class) + )) + .criterion("Die Größe der Liste wird um 1 verringert.", false, "testSize", JsonParameterSet.class) + .criterion("Das entfernte Element verweist immernoch auf seine Nachbarn.", "testReference", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.2.5 for task H10.2. + */ + private static final Subtask H10_2_5 = Subtask.builder() + .description("H10.2.5 | Alle Elemente entfernen") + .testClassName("h10.H10_2_5_Tests") + .criterion("Nach einem Aufruf von clear() ist die Liste leer. Insbesondere sind head und tail auf null gesetzt, und die Größe der Liste ist 0.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the task H10.2. + */ + private static final Task H10_2 = Task.builder() + .description("H10.2 | DoublyLinkedList") + .subtasks(H10_2_1, H10_2_2, H10_2_3, H10_2_4, H10_2_5) + .build(); + + /** + * Defines the subtask H10.3.1 for task H10.3. + */ + private static final Subtask H10_3_1 = Subtask.builder() + .description("H10.3.1 | Das nächste Element zurückgeben") + .testClassName("h10.H10_3_1_Tests") + .criterion("Die Methode hasNext() gibt korrekt an, ob es ein nächstes Element gibt.", "testHasNext") + .criterion("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.", Map.of( + "testNextEmpty", List.of(), + "testNextEnd", List.of(), + "testNextMiddle", List.of() + )) + .criterion("Die Methode next() setzt das Attribut calledRemove auf false.", "testCalledRemove") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.3.2 for task H10.3. + */ + private static final Subtask H10_3_2 = Subtask.builder() + .description("H10.3.2 | Das vorherige Element zurückgeben") + .testClassName("h10.H10_3_2_Tests") + .criterion("Die Methode hasPrevious() gibt korrekt an, ob es ein vorheriges Element gibt.", false, "testHasPrevious") + .criterion("Die Methode previous() gibt das vorherige Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.", false, Map.of( + "testPreviousEmpty", List.of(), + "testPreviousEnd", List.of(), + "testNextMiddle", List.of() + )) + .criterion("Die Methode previous() setzt das Attribut calledRemove auf false.", false, "testCalledRemove") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.3.3 for task H10.3. + */ + private static final Subtask H10_3_3 = Subtask.builder() + .description("H10.3.3 | Verlierer des Spiels bestimmen") + .testClassName("h10.H10_3_3_Tests") + .criterion("Bei einem SKIP wird der nächste Spieler übersprungen.", "testSkip") + .criterion("Bei einer REVERSE-Karte wird die Richtung des Iterators umgekehrt.", "testReverse") + .criterion("Wurde im letzten Zug eine DRAW_TWO-Karte gespielt, so muss der nächste Spieler zwei Karten ziehen, sofern er nicht auch eine DRAW_TWO-Karte spielt.", false, Map.of( + "testDrawTwoLastTurnNoDrawTwo", List.of(), + "testDrawTwoLastTurnDrawTwo", List.of() + )) + .criterion("Wurden in den vorherigen Zügen mehrere DRAW_TWO-Karten gespielt, so erhöht sich die Anzahl der zu ziehenden Karten entsprechend.", false, "testDrawTwoMultiple") + .criterion("Spieler, die keine Karten mehr auf der Hand haben, werden aus dem Spiel entfernt.", "testNoCards") + .criterion("Der Spieler, der als letztes Karten in der Hand hat, wird korrekt bestimmt und zurückgegeben.", false, "testLoser", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the task H10.3. + */ + private static final Task H10_3 = Task.builder() + .description("H10.3 | Zyklischer Iterator über die DoublyLinkedList") + .subtasks(H10_3_1, H10_3_2, H10_3_3) + .build(); + + /** + * Whether the private tests are being graded. + */ + private final boolean publicTests; + + /** + * Constructs a new rubric provider. + * + * @param publicTests whether the private tests are being graded + */ + public H10_RubricProvider(boolean publicTests) { + this.publicTests = publicTests; + } + + /** + * Constructs a new public rubric provider. + */ + public H10_RubricProvider() { + this(true); + } + + @Override + public Rubric getRubric() { + return Rubric.builder() + .title("H10 | Doppelt verkette Listen - %s Tests".formatted(publicTests ? "Public" : "Private")) + .addChildCriteria( + Stream.of(H10_1, H10_2, H10_3) + .map(Task::getCriterion) + .toArray(Criterion[]::new) + ) + .build(); + } +} diff --git a/H10/src/graderPublic/java/h10/rubric/H10_Tests.java b/H10/src/graderPublic/java/h10/rubric/H10_Tests.java new file mode 100644 index 0000000..880cad8 --- /dev/null +++ b/H10/src/graderPublic/java/h10/rubric/H10_Tests.java @@ -0,0 +1,155 @@ +package h10.rubric; + +import h10.assertions.Links; +import h10.assertions.TestConstants; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.List; + +/** + * Defines a test skeleton for the H10 assignment. + * + *

Use the following schema: + *

{@code
+ *     public class TestClass extends H10_Test {
+ *          public static final Map> CUSTOM_CONVERTERS = Map.of(
+ *              ...
+ *          );
+ *
+ *          @Override
+ *          public Class getClassType() {
+ *              return ...
+ *          }
+ *
+ *          @Override
+ *          public String getMethodName() {
+ *              return "...";
+ *          }
+ *
+ *          @Override
+ *          public List> getMethodParameters() {
+ *              return List.of(...);
+ *          }
+ *
+ *          @ParameterizedTest
+ *          @JsonParameterSetTest(value = "path-to-json-data.json", customConverters = CUSTOM_CONVERTERS)
+ *          void testXYZ(JsonParameterSet parameters) {
+ *              ...
+ *          }
+ *   }
+ * }
+ * + * @author Nhan Huynh + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@TestForSubmission +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public abstract class H10_Tests { + + /** + * The attribute name for custom converters in the JSON parameter set test annotation. + */ + public static final String CUSTOM_CONVERTERS = "CONVERTERS"; + + /** + * The type of the class under test. + */ + private @Nullable TypeLink type; + + /** + * The method under test. + */ + private @Nullable MethodLink method; + + /** + * Configuration for all tests. + */ + @BeforeAll + void globalSetup() { + Assertions.assertNotNull( + getClass().getAnnotation(TestForSubmission.class), + "The test class is not annotated with @TestForSubmission." + ); + + this.type = Links.getType(getClassType()); + this.method = Links.getMethod( + type, + getMethodName(), + Matcher.of(method -> method.typeList().equals(getMethodParametersLink())) + ); + } + + /** + * Returns the class type of the class under test. + * + * @return the class type of the class under test + */ + public abstract Class getClassType(); + + /** + * Returns the name of the method under test. + * + * @return the name of the method under test + */ + public abstract String getMethodName(); + + /** + * Return the parameter types of the method under test. + * + * @return the parameter types of the method under test + */ + public abstract List> getMethodParameters(); + + /** + * Return the parameter types of the method under test. + * + * @return the parameter types of the method under test + */ + public List getMethodParametersLink() { + return getMethodParameters().stream().map(BasicTypeLink::of).toList(); + } + + /** + * Returns the type of the class under test. + * + * @return the type of the class under test + */ + public TypeLink getType() { + if (type == null) { + throw new IllegalStateException("Type not initialized"); + } + return type; + } + + /** + * Returns the method under test. + * + * @return the method under test + */ + public MethodLink getMethod() { + if (method == null) { + throw new IllegalStateException("Method not initialized"); + } + return method; + } + + /** + * Returns a context builder with the method under test as the subject. + * + * @return a context builder with the method under test as the subject + */ + public Context.Builder contextBuilder() { + return Assertions2.contextBuilder().subject(getMethod().reflection()); + } +} diff --git a/H10/src/graderPublic/java/h10/rubric/Subtask.java b/H10/src/graderPublic/java/h10/rubric/Subtask.java new file mode 100644 index 0000000..2e548b4 --- /dev/null +++ b/H10/src/graderPublic/java/h10/rubric/Subtask.java @@ -0,0 +1,312 @@ +package h10.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Gradable; +import org.sourcegrade.jagr.api.rubric.Grader; +import org.sourcegrade.jagr.api.rubric.JUnitTestRef; +import org.tudalgo.algoutils.tutor.general.jagr.RubricUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/** + * Represents a subtask in a rubric. + * + * @param description a short description of the subtask + * @param criteria the subtasks that must be met to complete the subtask + * @param requirements the requirements that must be met to complete the subtask + * @author Nhan Huynh + */ +public record Subtask( + String description, + List criteria, + List requirements +) implements Criteriable { + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + * + * @return a new subtask builder + */ + public static SubtaskBuilder builder() { + return new SubtaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .minPoints(0) + .addChildCriteria(Stream.concat(criteria.stream(), requirements.stream()).toArray(Criterion[]::new)) + .build(); + } + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + */ + public interface SubtaskBuilder extends Builder { + + /** + * Sets the description of the subtask. + * + * @param description the description of the subtask + * @return this builder instance with the description set + */ + SubtaskBuilder description(String description); + + /** + * Sets the name of the test class that tests this subtask. + * + * @param testClassName the name of the test class that tests this subtask + * @return this builder instance with the test class name set + */ + SubtaskBuilder testClassName(String testClassName); + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodsSignature the signature of the test methods + * @return this builder instance with the criterion added + */ + SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ); + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodsSignature the signature of the test methods + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, Map>> testMethodsSignature) { + return criterion(description, true, testMethodsSignature); + } + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion( + String description, + boolean publicTest, + String testMethodName, + Class... testMethodParameters + ) { + return criterion(description, publicTest, Map.of(testMethodName, List.of(testMethodParameters))); + } + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodName the name of the test method + * @param testMethodSignature the signature of the test method + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, String testMethodName, Class... testMethodSignature) { + return criterion(description, true, testMethodName, testMethodSignature); + } + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodsSignature the signature of the test methods + * @return this builder instance with the requirement added + */ + SubtaskBuilder requirement(String description, Map>> testMethodsSignature); + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * @return this builder instance with the requirement added + */ + default SubtaskBuilder requirement(String description, String testMethodName, Class... testMethodParameters) { + return requirement(description, Map.of(testMethodName, List.of(testMethodParameters))); + } + } + + /** + * A builder for building {@link Subtask} instances. + */ + private static class SubtaskCriteriaBuilderImpl implements SubtaskBuilder { + + /** + * The description of the subtask. + */ + private @NotNull String description = ""; + + /** + * The name of the test class that tests this subtask. + */ + private @NotNull String testClassName = ""; + + /** + * The subtasks of the subtask. + */ + private final List> criteria = new ArrayList<>(); + + /** + * The requirements of the subtask. + */ + private final List> requirements = new ArrayList<>(); + + @Override + public SubtaskBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public SubtaskBuilder testClassName(String testClassName) { + this.testClassName = testClassName; + return this; + } + + /** + * Returns the description of the subtask. + * + * @return the description of the subtask + */ + private @NotNull String getDescription() { + return description; + } + + /** + * Returns a pre-configured criterion builder where the description and grader are set. + * + * @param description the description of the criterion + * @param grader the grader of the criterion + * @return a pre-configured criterion builder with the description and grader set + */ + private Criterion.Builder criterionBuilder(String description, Grader grader) { + return Criterion.builder() + .shortDescription(description) + .grader(grader); + } + + /** + * Returns a pre-configured criterion builder where the description and test reference are set. + * + * @param description the description of the criterion + * @param testRef the test reference of the criterion + * @return a pre-configured criterion builder with the description and test reference set + */ + private Criterion.Builder criterionBuilder(String description, JUnitTestRef testRef) { + return criterionBuilder( + description, + Grader.testAwareBuilder() + .requirePass(testRef) + .pointsFailedMin() + .pointsPassedMax() + .build() + ); + } + + /** + * Creates a criterion supplier with the given description, class name, test methods signature, and points. + * Since the points can only be determined after all subtasks are added, the points are calculated lazily. + * + * @param description the description of the criterion + * @param className the name of the test class that tests this subtask + * @param testMethodsSignature the signature of the test methods + * @param points the points of the criterion + * @return a criterion supplier with the given description, class name, test methods signature, and points + */ + private Supplier criterion( + String description, + String className, + Map>> testMethodsSignature, + Supplier points + ) { + return () -> { + Criterion.Builder builder; + try { + List testRefs = new ArrayList<>(testMethodsSignature.size()); + for (Map.Entry>> entry : testMethodsSignature.entrySet()) { + Method method = Class.forName(className).getDeclaredMethod( + entry.getKey(), + entry.getValue().toArray(Class[]::new) + ); + testRefs.add(JUnitTestRef.ofMethod(method)); + } + builder = criterionBuilder(description, JUnitTestRef.and(testRefs.toArray(JUnitTestRef[]::new))); + } catch (Exception e) { + builder = criterionBuilder(description, RubricUtils.graderPrivateOnly()); + } + int pointsValue = points.get(); + if (pointsValue >= 0) { + builder.minPoints(0); + builder.maxPoints(pointsValue); + } else { + builder.maxPoints(0); + builder.minPoints(pointsValue); + } + return builder.build(); + }; + } + + @Override + public SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ) { + criteria.add( + criterion( + description, + testClassName + (publicTest ? "Public" : "Private"), + testMethodsSignature, + () -> 1 + ) + ); + return this; + } + + @Override + public SubtaskBuilder requirement(String description, Map>> testMethodsSignature) { + requirements.add( + criterion( + description, + testClassName + "Private", + testMethodsSignature, + () -> -criteria.stream() + .map(Supplier::get) + .mapToInt(Gradable::getMaxPoints) + .sum() + ) + ); + return this; + } + + @Override + public Subtask build() { + if (testClassName.isBlank()) { + throw new IllegalStateException("Test class name must be set"); + } + return new Subtask( + description, + criteria.stream().map(Supplier::get).toList(), + requirements.stream().map(Supplier::get).toList() + ); + } + } +} diff --git a/H10/src/graderPublic/java/h10/rubric/Task.java b/H10/src/graderPublic/java/h10/rubric/Task.java new file mode 100644 index 0000000..bd97064 --- /dev/null +++ b/H10/src/graderPublic/java/h10/rubric/Task.java @@ -0,0 +1,101 @@ +package h10.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a task in a rubric. + * + * @param description a short description of the task + * @param subtasks the subtasks that must be met to complete the task + */ +public record Task(String description, List subtasks) implements Criteriable { + + /** + * Returns a new {@link TaskCriteriaBuilder} to build a {@link Task}. + * + * @return a new task subtasks builder + */ + public static TaskCriteriaBuilder builder() { + return new TaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .addChildCriteria(subtasks.stream().map(Subtask::getCriterion).toArray(Criterion[]::new)) + .build(); + } + + /** + * + */ + public interface TaskCriteriaBuilder extends Builder { + + /** + * Sets the description of the task. + * + * @param description the description of the task + * @return this builder instance with the description set + */ + TaskCriteriaBuilder description(String description); + + /** + * Adds subtasks to the task. + * + * @param subtasks the subtasks to add + * @return this builder instance with the subtasks added + */ + TaskCriteriaBuilder subtasks(Subtask... subtasks); + + /** + * Adds a criterion to the task. + * + * @param criterion the criterion to add + * @return this builder instance with the criterion added + */ + default TaskCriteriaBuilder subtask(Subtask criterion) { + return subtasks(criterion); + } + } + + /** + * A builder for building {@link Task} instances. + */ + private static class TaskCriteriaBuilderImpl implements TaskCriteriaBuilder { + + /** + * The description of the task. + */ + private @NotNull String description = ""; + + /** + * The subtasks of the task. + */ + private final List criteria = new ArrayList<>(); + + @Override + public TaskCriteriaBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public TaskCriteriaBuilder subtasks(Subtask... subtasks) { + this.criteria.addAll(List.of(subtasks)); + return this; + } + + @Override + public Task build() { + if (description.isBlank()) { + throw new IllegalArgumentException("Description cannot be blank"); + } + return new Task(description, criteria); + } + } +} diff --git a/H10/src/graderPublic/java/h10/util/ListItems.java b/H10/src/graderPublic/java/h10/util/ListItems.java new file mode 100644 index 0000000..7e1a5a9 --- /dev/null +++ b/H10/src/graderPublic/java/h10/util/ListItems.java @@ -0,0 +1,92 @@ +package h10.util; + +import h10.ListItem; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; +import javax.annotation.Nullable; + +/** + * Utility class for working with {@link ListItem}s. + * + * @author Nhan Huynh + */ +public final class ListItems { + + /** + * Prevent instantiation of this utility class. + */ + private ListItems() { + } + + /** + * Returns an {@link Iterator} over the {@link ListItem}s in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return an iterator over the list + */ + public static Iterator> itemIterator(ListItem head) { + return itemStream(head).iterator(); + } + + /** + * Returns an {@link Iterator} over the elements in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return an iterator over the elements in the list + */ + public static Iterator iterator(ListItem head) { + return stream(head).iterator(); + } + + /** + * Returns a {@link Stream} over the {@link ListItem}s in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return a stream over the list + */ + public static Stream> itemStream(ListItem head) { + return Stream.iterate(head, Objects::nonNull, item -> item.next); + } + + /** + * Returns a {@link Stream} over the elements in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return a stream over the elements in the list + */ + public static Stream stream(ListItem head) { + return itemStream(head).map(item -> item.key); + } + + @SafeVarargs + public static ListItem of(T... elements) { + return toItems(List.of(elements)); + } + + /** + * Converts a list of elements to a linked list of {@link ListItem}s. + * + * @param elements the elements to convert + * @param the type of the elements + * @return the head of the list + */ + public static @Nullable ListItem toItems(List elements) { + if (elements.isEmpty()) { + return null; + } + List> items = elements.stream().map(ListItem::new).toList(); + items.stream().reduce((tail, item) -> { + tail.next = item; + item.prev = tail; + return item; + }).orElseThrow(); + return items.getFirst(); + } +} diff --git a/H10/src/graderPublic/java/h10/util/MockList.java b/H10/src/graderPublic/java/h10/util/MockList.java new file mode 100644 index 0000000..9587bc3 --- /dev/null +++ b/H10/src/graderPublic/java/h10/util/MockList.java @@ -0,0 +1,150 @@ +package h10.util; + +import h10.BidirectionalIterator; +import h10.MyList; + +import java.util.ArrayList; +import java.util.ListIterator; + +/** + * A simple implementation of a list that can be used for testing. + * + * @param the type of the elements in the list + */ +public class MockList implements MyList { + + /** + * The delegate list that holds the elements. + */ + private final java.util.List delegate = new ArrayList<>(); + + + /** + * Creates a list with the given elements. + * + * @param elements the elements to add to the list + * @param the type of the elements in the list + * @return the list with the given elements + */ + @SafeVarargs + public static MockList of(T... elements) { + return of(java.util.List.of(elements)); + } + + /** + * Creates a list with the given elements. + * + * @param elements the elements to add to the list + * @param the type of the elements in the list + * @return the list with the given elements + */ + public static MockList of(Iterable elements) { + MockList list = new MockList<>(); + for (T element : elements) { + list.add(element); + } + return list; + } + + @Override + public int findFirst(T key) { + return delegate.indexOf(key); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public T get(int index) { + return delegate.get(index); + } + + @Override + public void add(int index, T key) { + delegate.add(index, key); + } + + @Override + public T removeAtIndex(int index) { + return delegate.remove(index); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public BidirectionalIterator cyclicIterator() { + return new BidirectionalIterator<>() { + + ListIterator it = delegate.listIterator(); + Boolean nextCalled = null; + Boolean removeCalled = false; + + @Override + public boolean hasNext() { + return size() > 0; + } + + private void checkResetNext() { + if (!it.hasNext()) { + it = delegate.listIterator(); + } + } + + private void checkResetPrevious() { + if (!it.hasPrevious()) { + it = delegate.listIterator(size()); + } + } + + @Override + public T next() { + checkResetNext(); + // Case when previous was called + // We need to skip the current element or else we will return the same element + if (nextCalled != null && !nextCalled) { + it.next(); + checkResetNext(); + } + + T next = it.next(); + nextCalled = true; + return next; + } + + @Override + public boolean hasPrevious() { + return size() > 0; + } + + @Override + public T previous() { + checkResetPrevious(); + // Case when next was called + // We need to skip the current element or else we will return the same element + if (nextCalled != null && nextCalled) { + it.previous(); + checkResetPrevious(); + } + T previous = it.previous(); + nextCalled = false; + return previous; + } + + @Override + public void remove() { + it.remove(); + removeCalled = true; + } + }; + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/H10/src/graderPublic/resources/h10/H10_1_1.json b/H10/src/graderPublic/resources/h10/H10_1_1.json new file mode 100644 index 0000000..6b31c72 --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_1_1.json @@ -0,0 +1,37 @@ +[ + { + "names": [ + ] + }, + { + "names": [ + "IU" + ] + }, + { + "names": [ + "Jo Youngmin", + "Jo Kwangmin" + ] + }, + { + "names": [ + "Han", + "Changbin", + "Bang Chan" + ] + }, + { + "names": [ + "Xiumin", + "Suho", + "Lay", + "Baekhyun", + "Chen", + "Chanyeol", + "D.O.", + "Kai", + "Sehun" + ] + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json b/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json new file mode 100644 index 0000000..cc15f0c --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json @@ -0,0 +1,234 @@ +[ + { + "deck": [ + "SKIP" + ], + "skips": 1 + }, + { + "deck": [ + "PASS", + "REVERSE" + ], + "skips": 0 + }, + { + "deck": [ + "SKIP", + "PASS", + "DRAW_TWO" + ], + "skips": 1 + }, + { + "deck": [ + "PASS", + "SKIP", + "REVERSE", + "DRAW_TWO", + "PASS" + ], + "skips": 1 + }, + { + "deck": [ + "REVERSE", + "SKIP", + "PASS", + "DRAW_TWO", + "SKIP", + "PASS", + "PASS", + "DRAW_TWO", + "REVERSE", + "SKIP" + ], + "skips": 3 + }, + { + "deck": [ + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP" + ], + "skips": 10 + }, + { + "deck": [ + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "SKIP", + "PASS", + "DRAW_TWO", + "REVERSE", + "SKIP", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "PASS", + "PASS", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "PASS", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "REVERSE", + "SKIP", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "PASS" + ], + "skips": 9 + }, + { + "deck": [ + "SKIP", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "REVERSE", + "SKIP", + "PASS", + "SKIP", + "PASS", + "DRAW_TWO", + "PASS", + "SKIP", + "PASS", + "DRAW_TWO", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "SKIP", + "REVERSE", + "PASS", + "DRAW_TWO", + "SKIP", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "PASS", + "SKIP", + "PASS", + "PASS", + "REVERSE", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "REVERSE", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "SKIP", + "PASS", + "PASS", + "PASS", + "DRAW_TWO", + "REVERSE", + "PASS", + "SKIP", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "REVERSE", + "SKIP", + "PASS", + "PASS", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "DRAW_TWO" + ], + "skips": 23 + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_1.json b/H10/src/graderPublic/resources/h10/H10_2_1.json new file mode 100644 index 0000000..a6c732c --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_1.json @@ -0,0 +1,76 @@ +[ + { + "list": [ + 1 + ], + "key": 1, + "index": 0 + }, + { + "list": [ + 1, + 1, + 1, + 1 + ], + "key": 1, + "index": 0 + }, + { + "list": [ + 5, + 3, + 1, + 7, + 9 + ], + "key": 5, + "index": 0 + }, + { + "list": [ + 5, + 3, + 1, + 7, + 9 + ], + "key": 1, + "index": 2 + }, + { + "list": [ + 5, + 3, + 1, + 7, + 9 + ], + "key": 9, + "index": 4 + }, + { + "list": [ + ], + "key": 1, + "index": -1 + }, + { + "list": [ + -1 + ], + "key": 1, + "index": -1 + }, + { + "list": [ + 2, + 6, + 4, + 8, + 10 + ], + "key": 1, + "index": -1 + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_2_Position.json b/H10/src/graderPublic/resources/h10/H10_2_2_Position.json new file mode 100644 index 0000000..53c26ad --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_2_Position.json @@ -0,0 +1,42 @@ +[ + { + "input": [ + 1 + ], + "index": 0, + "element": 1 + }, + { + "input": [ + 5, + 1, + 3, + 2, + 4 + ], + "index": 0, + "element": 5 + }, + { + "input": [ + 5, + 1, + 3, + 2, + 4 + ], + "index": 2, + "element": 3 + }, + { + "input": [ + 5, + 1, + 3, + 2, + 4 + ], + "index": 4, + "element": 4 + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json b/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json new file mode 100644 index 0000000..87f9c03 --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json @@ -0,0 +1,92 @@ +[ + { + "input": [ + ], + "index": 1, + "key": 4 + }, + { + "input": [ + ], + "index": -1, + "key": 4 + }, + { + "input": [ + 5, + 22, + 9, + 12, + 15, + 3, + 7, + 8, + 10, + 11, + 13, + 14, + 16, + 17, + 18, + 19, + 20, + 21, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37 + ], + "index": 34, + "key": 4 + }, + { + "input": [ + 5, + 22, + 9, + 12, + 15, + 3, + 7, + 8, + 10, + 11, + 13, + 14, + 16, + 17, + 18, + 19, + 20, + 21, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37 + ], + "index": -43, + "key": 4 + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_3_Start.json b/H10/src/graderPublic/resources/h10/H10_2_3_Start.json new file mode 100644 index 0000000..2c722ac --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_3_Start.json @@ -0,0 +1,50 @@ +[ + { + "input": [ + 25 + ], + "key": 55, + "expected": [ + 55, + 25 + ] + }, + { + "input": [ + 25, + 69 + ], + "key": 55, + "expected": [ + 55, + 25, + 69 + ] + }, + { + "input": [ + 25, + 69, + 12, + 9, + 10, + 23, + 45, + 55, + 26 + ], + "key": 55, + "expected": [ + 55, + 25, + 69, + 12, + 9, + 10, + 23, + 45, + 55, + 26 + ] + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json b/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json new file mode 100644 index 0000000..f32a601 --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json @@ -0,0 +1,30 @@ +[ + { + "input": [ + 1, + 3, + 5 + ], + "key": 3, + "expected": [ + 1, + 5 + ] + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5 + ], + "key": 3, + "expected": [ + 1, + 2, + 4, + 5 + ] + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_4_References.json b/H10/src/graderPublic/resources/h10/H10_2_4_References.json new file mode 100644 index 0000000..e1f5a34 --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_4_References.json @@ -0,0 +1,26 @@ +[ + { + "input": [ + 11, + 22, + 33 + ], + "key": 11 + }, + { + "input": [ + 11, + 22, + 33 + ], + "key": 22 + }, + { + "input": [ + 11, + 22, + 33 + ], + "key": 33 + } +] diff --git a/H10/src/graderPublic/resources/h10/H10_2_5.json b/H10/src/graderPublic/resources/h10/H10_2_5.json new file mode 100644 index 0000000..e17805c --- /dev/null +++ b/H10/src/graderPublic/resources/h10/H10_2_5.json @@ -0,0 +1,36 @@ +[ + { + "input": [ + 3 + ] + }, + { + "input": [ + 3, + 1 + ] + }, + { + "input": [ + 3, + 1, + 2 + ] + }, + { + "input": [ + 3, + 1, + 1, + 2, + 4, + 6, + 9, + 2, + 1, + 2, + 4, + 7 + ] + } +] diff --git a/H10/src/main/java/h10/BidirectionalIterator.java b/H10/src/main/java/h10/BidirectionalIterator.java new file mode 100644 index 0000000..63f87d2 --- /dev/null +++ b/H10/src/main/java/h10/BidirectionalIterator.java @@ -0,0 +1,60 @@ +package h10; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * An iterator over elements that can be traversed in both directions. + * + * @param the type of elements returned by this iterator + */ +@DoNotTouch +public interface BidirectionalIterator extends Iterator { + + /** + * Returns {@code true} if this iterator has more elements when + * traversing the list in the forward direction. + * + * @return {@code true} if the list iterator has more elements when traversing the list in the forward direction + */ + boolean hasNext(); + + /** + * Returns the next element in the iteration and advances the cursor position. + * This method may be called repeatedly to iterate through the list, + * or intermixed with calls to {@link #previous} to go back and forth. + * + * @return the next element in the iteration + * @throws NoSuchElementException if there are no more elements to iterate over + */ + T next(); + + + /** + * Returns {@code true} if this iterator has more elements when + * traversing the list in the reverse direction. + * + * @return {@code true} if the iteration has more elements in the reverse direction + */ + boolean hasPrevious(); + + /** + * Returns the previous element in the iteration and moves the cursor position backwards. + * This method may be called repeatedly to iterate through the list, + * or intermixed with calls to {@link #next} to go back and forth. + * + * @return the previous element in the iteration + * @throws NoSuchElementException if there are no more elements to iterate over + */ + T previous(); + + /** + * Removes the last element that was returned. + * + * @throws IllegalStateException if the `next` or `previous` method has not been called yet or the element has + * already been removed + */ + void remove(); +} diff --git a/H10/src/main/java/h10/CardGame.java b/H10/src/main/java/h10/CardGame.java new file mode 100644 index 0000000..e81211c --- /dev/null +++ b/H10/src/main/java/h10/CardGame.java @@ -0,0 +1,147 @@ +package h10; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * Represents a simple card game with four players and a deck of cards. + */ +public class CardGame { + + /** + * The players in the game. + */ + @DoNotTouch + MyList players; + + /** + * An iterator over the players in the game. + */ + @DoNotTouch + private BidirectionalIterator iter; + + /** + * The deck of cards that are used in the game. + */ + @DoNotTouch + private MyList cardDeck; + + // Game state variables + + /** + * The direction of play in the game which determines the order in which the players take turns. + */ + @DoNotTouch + boolean reverseDirection = false; + + /** + * The state of the next player in the game. If true, the next player is skipped. + */ + @DoNotTouch + boolean skipNextPlayer = false; + + /** + * The number of cards the next player has to draw in the game. + */ + @DoNotTouch + int takeCards = 0; + + /** + * The current player in the game whose turn it is. + */ + @DoNotTouch + @Nullable CardGamePlayer currentPlayer = null; + + /** + * The card that is played in the current turn. + */ + @DoNotTouch + @Nullable PlayingCard currentCard = null; + + @DoNotTouch + private CardGame() { + } + + /** + * Creates a new card game with the given players and card deck. + * + * @param players the players in the game + * @param cardDeck the deck of cards used in the game + */ + @DoNotTouch + public CardGame(MyList players, MyList cardDeck) { + this.players = players; + this.cardDeck = cardDeck; + this.iter = this.players.cyclicIterator(); + } + + /** + * Creates a new card game with four players and a deck of 100 cards. + * + *

The deck is shuffled and each player gets five random cards. + * + * @return a new card game with four players and a deck of 100 cards + */ + @DoNotTouch + public static CardGame generateRandomCardGame() { + CardGame cardGame = new CardGame(); + + cardGame.players = new DoublyLinkedList<>(); + cardGame.cardDeck = new DoublyLinkedList<>(); + + // Create a card deck with 100 random cards + PlayingCard[] cards = PlayingCard.values(); + for (int i = 0; i < 100; i++) { + cardGame.cardDeck.add(cards[(int) (Math.random() * 4)]); + } + + // 4 players with 5 cards each + for (int i = 1; i < 5; i++) { + CardGamePlayer player = new CardGamePlayer("Player " + i); + cardGame.players.add(player); + for (int j = 0; j < 5; j++) { + player.takeCard(cardGame.cardDeck.removeAtIndex(0)); + } + } + + cardGame.iter = cardGame.players.cyclicIterator(); + + return cardGame; + } + + /** + * Determines the loser of the game. + * + * @return the last player who still has cards in their hand + */ + @DoNotTouch + public CardGamePlayer determineLoser() { + while (players.size() > 1) { + doTurn(); + } + + return players.get(0); + } + + /** + * Executes a turn in the game. + */ + @StudentImplementationRequired("H10.3.3") + private void doTurn() { + crash(); // TODO: Implement H10.3.3 + } + + @Override + @DoNotTouch + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < players.size(); i++) { + sb.append(players.get(i).toString()); + sb.append("\n"); + } + return sb.toString(); + } +} diff --git a/H10/src/main/java/h10/CardGamePlayer.java b/H10/src/main/java/h10/CardGamePlayer.java new file mode 100644 index 0000000..acb11a3 --- /dev/null +++ b/H10/src/main/java/h10/CardGamePlayer.java @@ -0,0 +1,83 @@ +package h10; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +/** + * Represents a player in the card game. + */ +@DoNotTouch +public class CardGamePlayer { + + /** + * The name of the player. + */ + @DoNotTouch + private final String name; + + /** + * The cards in the player's hand. + */ + @DoNotTouch + final MyList hand; + + /** + * Creates a new player with the given name. + * + * @param name the name of the player + */ + @DoNotTouch + public CardGamePlayer(String name) { + this.name = name; + this.hand = new DoublyLinkedList<>(); + } + + /** + * Returns the name of the player. + */ + @DoNotTouch + public String getName() { + return name; + } + + /** + * Plays the next card from the player's hand. + * + * @param prioritizeDrawTwo if true, the player will prioritize playing a DRAW_TWO card + * @return the card that was played + */ + @DoNotTouch + public PlayingCard playNextCard(boolean prioritizeDrawTwo) { + if (prioritizeDrawTwo) { + int index = hand.findFirst(PlayingCard.DRAW_TWO); + + if (index != -1) { // Player has a DRAW_TWO card on his hand, prioritize this card + return hand.removeAtIndex(index); + } + } + return hand.removeAtIndex(0); + } + + /** + * Adds a card to the player's hand. + * + * @param card the card to add + */ + @DoNotTouch + public void takeCard(PlayingCard card) { + hand.add(card); + } + + /** + * Returns the number of cards in the player's hand. + */ + @DoNotTouch + public int getHandSize() { + return hand.size(); + } + + @Override + @DoNotTouch + public String toString() { + return name + ": " + hand; + } +} diff --git a/H10/src/main/java/h10/DoublyLinkedList.java b/H10/src/main/java/h10/DoublyLinkedList.java new file mode 100644 index 0000000..83766dd --- /dev/null +++ b/H10/src/main/java/h10/DoublyLinkedList.java @@ -0,0 +1,258 @@ +package h10; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.NoSuchElementException; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * A doubly linked list implementation. + * + * @param the type of elements stored in the list + * @author Manuel Peters + */ +public class DoublyLinkedList implements MyList { + + /** + * The head of the doubly linked list. Points to the first element in the list. + */ + @DoNotTouch + ListItem head; + + /** + * The tail of the doubly linked list. Points to the last element in the list. + */ + @DoNotTouch + ListItem tail; + + /** + * The size of the doubly linked list. + */ + @DoNotTouch + int size; + + /** + * Constructs an empty doubly linked list. + */ + @DoNotTouch + public DoublyLinkedList() { + this.head = null; + this.tail = null; + this.size = 0; + } + + + @DoNotTouch + @Override + public int findFirst(T key) { + return findFirstHelper(head, key, 0); + } + + /** + * Helper method to find the first occurrence of an element in the list recursively. + * + * @param p the current ListItem + * @param key the element to be checked for presence in the list + * @param index the index of the current ListItem + * @return the index of the element if the element is present, -1 otherwise + */ + @StudentImplementationRequired("H10.2.1") + private int findFirstHelper(ListItem p, T key, int index) { + return crash(); // TODO: H10.2.1 + } + + @DoNotTouch + @Override + public int size() { + return size; + } + + @DoNotTouch + @Override + public T get(int index) { + return getListItem(index).key; + } + + /** + * Retrieves the ListItem at the specified index in the doubly linked list. + * + * @param index the index of the ListItem to retrieve + * @return the ListItem at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + */ + @StudentImplementationRequired("H10.2.2") + private ListItem getListItem(int index) { + return crash(); // TODO: H10.2.2 + } + + @DoNotTouch + @Override + public void add(T key) { + add(size, key); + } + + @StudentImplementationRequired("H10.2.3") + @Override + public void add(int index, @Nullable T key) { + crash(); // TODO: H10.2.3 + } + + /** + * Removes the specified ListItem from the doubly linked list. + * + * @param p the ListItem to be removed + * @return the key of the removed ListItem + */ + @StudentImplementationRequired("H10.2.4") + private T removeListItem(ListItem p) { + return crash(); // TODO: H10.2.4 + } + + @DoNotTouch + @Override + public T removeAtIndex(int index) { + ListItem p = getListItem(index); + return removeListItem(p); + } + + @StudentImplementationRequired("H10.2.5") + @Override + public void clear() { + crash(); // TODO: H10.2.5 + } + + /** + * An iterator for traversing a doubly linked list in a cyclic manner. + */ + class CyclicIterator implements BidirectionalIterator { + + /** + * The current ListItem of the iterator in the doubly linked list. + */ + @DoNotTouch + ListItem p; + + /** + * Indicates whether the `remove` method has been called after the last call to the `next` or `previous` method. + */ + @DoNotTouch + boolean calledRemove; + + /** + * Constructs a new cyclic iterator. + */ + @DoNotTouch + public CyclicIterator() { + this.p = null; + this.calledRemove = false; + } + + /** + * Returns {@code true} if this iterator has more elements when + * traversing the list in the forward direction. + * + * @return {@code true} if the list iterator has more elements when traversing the list in the forward direction + */ + @Override + @StudentImplementationRequired("H10.3.1") + public boolean hasNext() { + return crash(); // TODO: H10.3.1 + } + + /** + * Returns the next element in the iteration and advances the cursor position. + * This method may be called repeatedly to iterate through the list, + * or intermixed with calls to {@link #previous} to go back and forth. + * + * @return the next element in the iteration + * @throws NoSuchElementException if there are no more elements to iterate over + */ + @Override + @StudentImplementationRequired("H10.3.1") + public T next() { + if (!hasNext()) { + throw new NoSuchElementException("The list is empty"); + } + + return crash(); // TODO: H10.3.1 + } + + /** + * Returns {@code true} if this iterator has more elements when + * traversing the list in the reverse direction. + * + * @return {@code true} if the iteration has more elements in the reverse direction + */ + @StudentImplementationRequired("H10.3.2") + public boolean hasPrevious() { + return crash(); // TODO: H10.3.2 + } + + /** + * Returns the previous element in the iteration and moves the cursor position backwards. + * This method may be called repeatedly to iterate through the list, + * or intermixed with calls to {@link #next} to go back and forth. + * + * @return the previous element in the iteration + * @throws NoSuchElementException if there are no more elements to iterate over + */ + @StudentImplementationRequired("H10.3.2") + public T previous() { + if (!hasPrevious()) { + throw new NoSuchElementException("The list is empty"); + } + + return crash(); // TODO: H10.3.2 + } + + /** + * Removes the last element that was returned. + * + * @throws IllegalStateException if the `next` or `previous` method has not been called yet or the element has + * already been removed + */ + @Override + @DoNotTouch + public void remove() { + if (p == null) { + throw new IllegalStateException("next or previous method has not been called yet"); + } else if (calledRemove) { + throw new IllegalStateException("Element has already been removed"); + } + + removeListItem(p); + calledRemove = true; + } + } + + @DoNotTouch + @Override + public BidirectionalIterator cyclicIterator() { + return new CyclicIterator(); + } + + /** + * Returns a string representation of the doubly linked list. + * The string representation consists of a list of the elements in the order they are stored, + * enclosed in square brackets ("[]"). Adjacent elements are separated by the characters ", " (comma and space). + * + * @return a string representation of the list + */ + @Override + @DoNotTouch + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (ListItem p = head; p != null; p = p.next) { + sb.append(p.key); + if (p.next == null) { + break; + } + sb.append(',').append(' '); + } + return sb.append(']').toString(); + } +} diff --git a/H10/src/main/java/h10/ListItem.java b/H10/src/main/java/h10/ListItem.java new file mode 100644 index 0000000..4273b11 --- /dev/null +++ b/H10/src/main/java/h10/ListItem.java @@ -0,0 +1,63 @@ +package h10; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +/** + * Represents a single item in a doubly linked list. + */ +@DoNotTouch +public class ListItem { + + /** + * The key which this item hold. + */ + public T key; + + /** + * The reference to the previous item. + */ + public ListItem prev; + + /** + * The reference to the next item. + */ + public ListItem next; + + /** + * Creates a new single item in a doubly linked list with the given key, previous and next item. + * + * @param key the key which this item should hold + * @param prev the previous item in the list + * @param next the next item in the list + */ + public ListItem(T key, ListItem prev, ListItem next) { + this.key = key; + this.prev = prev; + this.next = next; + } + + /** + * Creates a new single item in a doubly linked list with the given key. + * + * @param key the key which this item should hold + */ + public ListItem(T key) { + this(key, null, null); + } + + /** + * Creates a new single item in a doubly linked list with no key, previous or next item. + */ + public ListItem() { + this(null, null, null); + } + + + @Override + public String toString() { + return "ListItem{" + + "key=" + + key + + '}'; + } +} diff --git a/H10/src/main/java/h10/ListItemExamples.java b/H10/src/main/java/h10/ListItemExamples.java new file mode 100644 index 0000000..4c156d1 --- /dev/null +++ b/H10/src/main/java/h10/ListItemExamples.java @@ -0,0 +1,59 @@ +package h10; + +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.Iterator; +import java.util.List; + +import static org.tudalgo.algoutils.student.Student.crash; + +public class ListItemExamples { + + /** + * Creates a doubly linked list of CardGamePlayer objects from an array of names. + * Each name in the array is used to create a CardGamePlayer object. + * The list is doubly linked, with each ListItem pointing to the next and previous ListItem. + * + * @param names an array of names to create CardGamePlayer objects + * @return the head of the doubly linked list of CardGamePlayer objects + */ + @StudentImplementationRequired("H10.1.1") + public static ListItem createPlayerListFromNames(String[] names) { + return crash(); // TODO: H10.1.1 + } + + /** + * Counts the number of SKIP cards in a doubly linked list of PlayingCard objects iteratively. + * + * @param cardDeck the head of the doubly linked list of PlayingCard objects + * @return the number of SKIP cards in the list + */ + @StudentImplementationRequired("H10.1.2") + public static int countSkipCardsIterative(ListItem cardDeck) { + return crash(); // TODO: H10.1.2 + } + + /** + * Counts the number of SKIP cards in a doubly linked list of PlayingCard objects recursively. + * + * @param cardDeck the head of the doubly linked list of PlayingCard objects + * @return the number of SKIP cards in the list + */ + @StudentImplementationRequired("H10.1.3") + public static int countSkipCardsRecursive(ListItem cardDeck) { + return crash(); // TODO: H10.1.3 + } + + /** + * Counts the number of SKIP cards in a list of PlayingCard objects using an iterator. + * + * @param cardDeck the list of PlayingCard objects + * @return the number of SKIP cards in the list + */ + @StudentImplementationRequired("H10.1.4") + @SuppressWarnings({"WhileLoopReplaceableByForEach", "ForLoopReplaceableByForEach"}) + public static int countSkipCardsIterator(List cardDeck) { + return crash(); // TODO: H10.1.4 + } + +} diff --git a/H10/src/main/java/h10/Main.java b/H10/src/main/java/h10/Main.java new file mode 100644 index 0000000..7d73c37 --- /dev/null +++ b/H10/src/main/java/h10/Main.java @@ -0,0 +1,20 @@ +package h10; + +/** + * Main entry point in executing the program. + */ +public class Main { + + /** + * Main entry point in executing the program. + * + * @param args program arguments, currently ignored + */ + public static void main(String[] args) { + // Manual testing + CardGame game = CardGame.generateRandomCardGame(); + System.out.println(game); + CardGamePlayer loser = game.determineLoser(); + System.out.println("The loser is: " + loser.getName()); + } +} diff --git a/H10/src/main/java/h10/MyList.java b/H10/src/main/java/h10/MyList.java new file mode 100644 index 0000000..9efd362 --- /dev/null +++ b/H10/src/main/java/h10/MyList.java @@ -0,0 +1,86 @@ +package h10; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +/** + * An ordered collection of elements, where the user has precise control over where in the + * list each element is inserted. + * + *

The user can access elements by their integer index (position in the list) and search for elements in the list. + * + * @param the type of elements stored in the list + */ +@DoNotTouch +public interface MyList { + + /** + * Checks if the list contains the specified element and returns the index of the first occurrence. + * + * @param key the element to be checked for presence in the list + * @return the index of the element if the element is present, -1 otherwise + */ + @DoNotTouch + int findFirst(T key); + + /** + * Returns the number of elements in the list. + * + * @return the number of elements in the list + */ + @DoNotTouch + int size(); + + /** + * Retrieves the element at the specified index in the doubly linked list. + * + * @param index the index of the element to retrieve + * @return the element at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + */ + @DoNotTouch + T get(int index); + + /** + * Adds a new element at the end of the doubly linked list. + * + * @param key the element to be added + * @throws IllegalArgumentException if the key is null + */ + @DoNotTouch + default void add(T key) { + add(size(), key); + } + + /** + * Adds a new element at the specified index in the doubly linked list. + * + * @param index the position at which the element is to be added + * @param key the element to be added + * @throws IllegalArgumentException if the key is null + * @throws IndexOutOfBoundsException if the index is invalid + */ + @DoNotTouch + void add(int index, T key); + + /** + * Removes the element at the specified position in the list. + * + * @param index the index of the element to be removed + * @return the element that was removed from the list + * @throws IndexOutOfBoundsException if the index is invalid + */ + @DoNotTouch + T removeAtIndex(int index); + + /** + * Removes all elements from the list. + */ + @DoNotTouch + void clear(); + + /** + * Retrieve an iterator for traversing this doubly linked list in a cyclic manner. + */ + @DoNotTouch + BidirectionalIterator cyclicIterator(); +} diff --git a/H10/src/main/java/h10/PlayingCard.java b/H10/src/main/java/h10/PlayingCard.java new file mode 100644 index 0000000..5cfddb6 --- /dev/null +++ b/H10/src/main/java/h10/PlayingCard.java @@ -0,0 +1,39 @@ +package h10; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +/** + * Represents a playing card in the card game. + * + *

The card can be one of the following: + * + *

    + *
  • PASS: no special action
  • + *
  • SKIP: the next player is skipped
  • + *
  • REVERSE: the direction of play is reversed
  • + *
  • DRAW_TWO: the next player draws two cards, unless they play a DRAW_TWO card themselves
  • + *
+ */ +@DoNotTouch +public enum PlayingCard { + + /** + * Represents a card that does nothing special. + */ + PASS, + + /** + * Represents a card that skips the next player. + */ + SKIP, + + /** + * Represents a card that reverses the direction of play. + */ + REVERSE, + + /** + * Represents a card that makes the next player draw two cards. + */ + DRAW_TWO +} diff --git a/H10/src/test/java/h10/ExampleJUnitTest.java b/H10/src/test/java/h10/ExampleJUnitTest.java new file mode 100644 index 0000000..c93cf8d --- /dev/null +++ b/H10/src/test/java/h10/ExampleJUnitTest.java @@ -0,0 +1,16 @@ +package h10; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * An example JUnit test class. + */ +public class ExampleJUnitTest { + + @Test + public void testAddition() { + assertEquals(2, 1 + 1); + } +} diff --git a/H11/.editorconfig b/H11/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/H11/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/H11/.gitignore b/H11/.gitignore new file mode 100644 index 0000000..e3750f8 --- /dev/null +++ b/H11/.gitignore @@ -0,0 +1,86 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +jagr.conf diff --git a/H11/README.md b/H11/README.md new file mode 100644 index 0000000..0c15519 --- /dev/null +++ b/H11/README.md @@ -0,0 +1,4 @@ +# Vorlage zu Hausübung 11 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/H11/build.gradle.kts b/H11/build.gradle.kts new file mode 100644 index 0000000..6b8a173 --- /dev/null +++ b/H11/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + alias(libs.plugins.algomate) +} + +exercise { + assignmentId.set("h11") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "" + firstName = "" + lastName = "" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h11.H11_RubricProviderPublic") + } + } +} diff --git a/H11/gradle/libs.versions.toml b/H11/gradle/libs.versions.toml new file mode 100644 index 0000000..46d58d4 --- /dev/null +++ b/H11/gradle/libs.versions.toml @@ -0,0 +1,2 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } diff --git a/H11/gradle/wrapper/gradle-wrapper.jar b/H11/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/H11/gradlew.bat b/H11/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/H11/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/H11/settings.gradle.kts b/H11/settings.gradle.kts new file mode 100644 index 0000000..9fda047 --- /dev/null +++ b/H11/settings.gradle.kts @@ -0,0 +1,10 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + } +} + +rootProject.name = "H11-Student" diff --git a/H11/src/graderPublic/java/h11/AlbumTest.java b/H11/src/graderPublic/java/h11/AlbumTest.java new file mode 100644 index 0000000..209277c --- /dev/null +++ b/H11/src/graderPublic/java/h11/AlbumTest.java @@ -0,0 +1,81 @@ +package h11; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import kotlin.Pair; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; + +@TestForSubmission +public class AlbumTest extends H11_Test { + + + @ParameterizedTest + @MethodSource("provideGetSongsLongerThan") + public void testGetSongsLongerThan(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetSongsLongerThan() { + return H11_Test.parseJsonFile("h11/Album_getSongsLongerThan.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetAverageDuration_empty") + public void testGetAverageDuration_empty(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .add("expected", expected) + .add("actual", actual.getSecond().returnValue()) + .build(); + + Assertions2.assertTrue( Math.abs((double) actual.getSecond().returnValue() - (double)expected) < 1E-10 , context, r -> "GetAverageDuration() did not return the expected value!"); + } + + private static Stream provideGetAverageDuration_empty() { + return H11_Test.parseJsonFile("h11/Album_getAverageDuration_empty.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetAverageDuration_full") + public void testGetAverageDuration_full(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .add("expected", expected) + .add("actual", actual.getSecond().returnValue()) + .build(); + + Assertions2.assertTrue( Math.abs((double) actual.getSecond().returnValue() - (double)expected) < 1E-10 , context, r -> "GetAverageDuration() did not return the expected value!"); + } + + private static Stream provideGetAverageDuration_full() { + return H11_Test.parseJsonFile("h11/Album_getAverageDuration_full.json"); + } + +} diff --git a/H11/src/graderPublic/java/h11/ArtistTest.java b/H11/src/graderPublic/java/h11/ArtistTest.java new file mode 100644 index 0000000..3f0c001 --- /dev/null +++ b/H11/src/graderPublic/java/h11/ArtistTest.java @@ -0,0 +1,75 @@ +package h11; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import kotlin.Pair; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; + +@TestForSubmission +public class ArtistTest extends H11_Test { + + @ParameterizedTest + @MethodSource("provideGetAllGenres_unique") + public void testGetAllGenres_unique(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllGenres_unique() { + return H11_Test.parseJsonFile("h11/Artist_getAllGenres_unique.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetAllSongs") + public void testGetAllSongs(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllSongs() { + return H11_Test.parseJsonFile("h11/Artist_getAllSongs.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetAllGenres_general") + public void testGetAllGenres_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllGenres_general() { + return H11_Test.parseJsonFile("h11/Artist_getAllGenres_general.json"); + } + +} diff --git a/H11/src/graderPublic/java/h11/H11_RubricProviderPublic.java b/H11/src/graderPublic/java/h11/H11_RubricProviderPublic.java new file mode 100644 index 0000000..8be6e37 --- /dev/null +++ b/H11/src/graderPublic/java/h11/H11_RubricProviderPublic.java @@ -0,0 +1,351 @@ +package h11; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.sourcegrade.jagr.api.rubric.*; + +import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.criterion; +import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.graderPrivateOnly; + +public class H11_RubricProviderPublic implements RubricProvider { + + private static final Criterion H11_1_1 = Criterion.builder() + .shortDescription("H11.1.1 | Lieder länger als ...") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode isLongerThan(int durationInSeconds) von Song gibt true zurück, wenn die Dauer des Songs länger als durationInSeconds ist, sonst false.", + JUnitTestRef.ofMethod(() -> SongTest.class.getDeclaredMethod("testIsLongerThan", ObjectNode.class)) + ), + criterion( + "Die Methode getSongsLongerThan(int durationInSeconds) von Album gibt alle Songs des Albums zurück, die länger als durationInSeconds sind.", + JUnitTestRef.ofMethod(() -> AlbumTest.class.getDeclaredMethod("testGetSongsLongerThan", ObjectNode.class)) + ) + ) + .build(); + + + private static final Criterion H11_1_2 = Criterion.builder() + .shortDescription("H11.1.2 | Durchschnittliche Spieldauer eines Albums") + .maxPoints(2) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getAverageDuration() von Album gibt die durchschnittliche Dauer aller Songs des Albums zurück.", + JUnitTestRef.ofMethod(() -> AlbumTest.class.getDeclaredMethod("testGetAverageDuration_full", ObjectNode.class)) + ), + criterion( + "Die Methode getAverageDuration() von Album gibt für ein Album ohne Lieder 0 zurück.", + JUnitTestRef.ofMethod(() -> AlbumTest.class.getDeclaredMethod("testGetAverageDuration_empty", ObjectNode.class)) + ) + ) + .build(); + + private static final Criterion H11_1 = Criterion.builder() + .shortDescription("H11.1 | Alben") + .addChildCriteria( + H11_1_1, + H11_1_2 + ) + .build(); + + + private static final Criterion H11_2_1 = Criterion.builder() + .shortDescription("H11.2.1 | Lieder eines Künstlers") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getAllSongs() von Artist gibt eine Liste aller Songs des Künstlers zurück.", + JUnitTestRef.ofMethod(() -> ArtistTest.class.getDeclaredMethod("testGetAllSongs", ObjectNode.class)) + ) + ) + .build(); + + + private static final Criterion H11_2_2 = Criterion.builder() + .shortDescription("H11.2.2 | Alle Genres eines Künstlers") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getAllGenres() von Artist gibt eine Liste aller Genres der Alben des Künstlers zurück.", + JUnitTestRef.ofMethod(() -> ArtistTest.class.getDeclaredMethod("testGetAllGenres_general", ObjectNode.class)) + ), + criterion( + "Jedes Genre kommt nur einmal in der Liste vor.", + JUnitTestRef.ofMethod(() -> ArtistTest.class.getDeclaredMethod("testGetAllGenres_unique", ObjectNode.class)) + ) + ) + .build(); + + private static final Criterion H11_2 = Criterion.builder() + .shortDescription("H11.2 | Künstler") + .addChildCriteria( + H11_2_1, + H11_2_2 + ) + .build(); + + + public static final Criterion H11_3_1 = Criterion.builder() + .shortDescription("H11.3.1 | Abgespielte Lieder") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getPlayedSongs() von User gibt eine Liste aller abgespielten Lieder des Benutzers zurück.", + JUnitTestRef.ofMethod(() -> UserTest.class.getDeclaredMethod("testGetPlayedSongs_general", ObjectNode.class)) + ), + criterion( + "Jedes Lied kommt nur einmal in der Liste vor.", + JUnitTestRef.ofMethod(() -> UserTest.class.getDeclaredMethod("testGetPlayedSongs_unique", ObjectNode.class)) + ) + ) + .build(); + + public static final Criterion H11_3_2 = Criterion.builder() + .shortDescription("H11.3.2 | Wie oft wurde ein Lied abgespielt?") + .maxPoints(3) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getPlayCounts() von User gibt eine Liste aller abgespielten Lieder des Benutzers zurück, zusammen mit der Anzahl der Wiedergaben.", + 2, + JUnitTestRef.ofMethod(() -> UserTest.class.getDeclaredMethod("testGetPlayCounts_return", ObjectNode.class)) + ), + privateCriterion( + "Die Liste ist absteigend nach der Anzahl der Wiedergaben sortiert. Bei gleicher Anzahl von Wiedergaben ist die Reihenfolge alphabetisch nach dem Titel des Liedes sortiert." + ) + ) + .build(); + + public static final Criterion H11_3_3 = Criterion.builder() + .shortDescription("H11.3.3 | Was ist das Lieblingslied?") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getFavoriteSong() von User gibt das am häufigsten abgespielte Lied des Benutzers zurück." + ), + privateCriterion( + "Hat der Benutzer noch kein Lied abgespielt, wird null zurückgegeben." + ) + ) + .build(); + + public static final Criterion H11_3_4 = Criterion.builder() + .shortDescription("H11.3.4 | Ausgabe der meistgespielten Lieder") + .maxPoints(2) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getTopPlayedSongsList() von User gibt eine Liste von maximal drei Liedern zurück." + ), + privateCriterion( + "Das Format der Ausgabe ist \" ( plays)\" pro Song." + ) + ) + .build(); + + public static final Criterion H11_3 = Criterion.builder() + .shortDescription("H11.3 | Analysieren von Nutzern") + .addChildCriteria( + H11_3_1, + H11_3_2, + H11_3_3, + H11_3_4 + ) + .build(); + + public static final Criterion H11_4_1 = Criterion.builder() + .shortDescription("H11.4.1 | Alle Lieder") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getAllSongs() von MusicStreaming gibt eine Liste aller Lieder zurück." + ), + privateCriterion( + "Jedes Lied kommt nur einmal in der Liste vor." + ) + ) + .build(); + + + public static final Criterion H11_4_2 = Criterion.builder() + .shortDescription("H11.4.2 | Eine neue zufällige Playlist") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode generateRandomPlaylist() von MusicStreaming erstellt einen unendlichen Stream von zufälligen Liedern.", + JUnitTestRef.ofMethod(() -> MusicStreamingTest.class.getDeclaredMethod("testGenerateRandomPlaylist", ObjectNode.class)) + ) + ) + .build(); + + public static final Criterion H11_4_3 = Criterion.builder() + .shortDescription("H11.4.3 | Nur Lieder bestimmter Länge") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getSongsLongerThan(int durationInSeconds) von MusicStreaming gibt nur Lieder zurück, die länger als durationInSeconds sind." + ) + ) + .build(); + + public static final Criterion H11_4_4 = Criterion.builder() + .shortDescription("H11.4.4 | Alle Genres") + .maxPoints(1) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getAllGenres() von MusicStreaming gibt eine Liste von in Alben verwendeten Genres zurück." + ), + privateCriterion( + "Jedes Genre kommt nur einmal in der Liste vor." + ) + ) + .build(); + + public static final Criterion H11_4_5 = Criterion.builder() + .shortDescription("H11.4.5 | Nur Alben eines Genres") + .maxPoints(2) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getAlbumsByGenre() von MusicStreaming gibt eine Map zurück, die jedes Genre auf eine Liste von Alben dieses Genres abbildet.", + 2 + ) + ) + .build(); + + public static final Criterion H11_4_6 = Criterion.builder() + .shortDescription("H11.4.6 | Meistgespielte Lieder") + .maxPoints(4) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getGlobalPlayCounts() von MusicStreaming gibt eine Liste aller Lieder und ihrer Gesamtanzahl von Wiedergaben zurück.", + JUnitTestRef.ofMethod(() -> MusicStreamingTest.class.getDeclaredMethod("testGetGlobalPlayCounts_general", ObjectNode.class)), + 2 + ), + privateCriterion( + "Die Liste ist absteigend nach der Anzahl der Wiedergaben sortiert. Bei gleicher Anzahl von Wiedergaben ist die Reihenfolge alphabetisch nach dem Titel des Liedes sortiert." + ), + privateCriterion( + "Die Methode getTopPlayedSongsList() von MusicStreaming gibt eine Liste von maximal fünf Liedern zurück. Das Format der Ausgabe ist \" ( plays)\" pro Song." + ) + ) + .build(); + + public static final Criterion H11_4_7 = Criterion.builder() + .shortDescription("H11.4.7 | Spielzeit eines Künstlers") + .maxPoints(4) + .minPoints(0) + .addChildCriteria( + privateCriterion( + "Die Methode getArtistPlayTime(Artist artist) von MusicStreaming gibt die Gesamtspielzeit in Sekunden aller Lieder des Künstlers zurück.", + 3 + ), + privateCriterion( + "Die Methode getArtistPlayTimes() von MusicStreaming gibt eine Map zurück, die jeden Künstler auf die Gesamtspielzeit in Sekunden seiner Lieder abbildet." + ) + ) + .build(); + + public static final Criterion H11_4_8 = Criterion.builder() + .shortDescription("H11.4.8 | Welcher Künstler wurde am meisten gehört?") + .maxPoints(2) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode getMostPlayedArtist() von MusicStreaming gibt den Künstler zurück, dessen Gesamtspielzeit am größten ist.", + JUnitTestRef.ofMethod(() -> MusicStreamingTest.class.getDeclaredMethod("testGetMostPlayedArtist_full", ObjectNode.class)) + ), + criterion( + "Hat noch kein Künstler Lieder, wird null zurückgegeben.", + JUnitTestRef.ofMethod(() -> MusicStreamingTest.class.getDeclaredMethod("testGetMostPlayedArtist_empty", ObjectNode.class)) + ) + ) + .build(); + + + public static final Criterion H11_4_9 = Criterion.builder() + .shortDescription("H11.4.9 | Suchen von Liedern") + .maxPoints(2) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode searchSongs(Predicate predicate) von MusicStreaming gibt eine Liste von Liedern zurück, die das gegebene Predicate erfüllen.", + JUnitTestRef.ofMethod(() -> MusicStreamingTest.class.getDeclaredMethod("testSearchSongs", ObjectNode.class)), + 2 + ) + ) + .build(); + + public static final Criterion H11_4_10 = Criterion.builder() + .shortDescription("H11.4.10 | Preiserhöhung") + .maxPoints(2) + .minPoints(0) + .addChildCriteria( + criterion( + "Die Methode adjustPrice(double percentage) von MusicStreaming erhöht oder senkt den Preis für alle Benutzer bei einem postiven bzw. negativen Prozentsatz.", + JUnitTestRef.ofMethod(() -> MusicStreamingTest.class.getDeclaredMethod("testAdjustPrice_general", ObjectNode.class)) + ), + privateCriterion( + "Die Methode adjustPrice(double percentage) von MusicStreaming erhält den Preis für alle Benutzer bei einem Prozentsatz von 0." + ) + ) + .build(); + + public static final Criterion H11_4 = Criterion.builder() + .shortDescription("H11.4 | Musikstreaming") + .addChildCriteria( + H11_4_1, + H11_4_2, + H11_4_3, + H11_4_4, + H11_4_5, + H11_4_6, + H11_4_7, + H11_4_8, + H11_4_9, + H11_4_10 + ) + .build(); + + public static final Rubric RUBRIC = Rubric.builder() + .title("H11 | Musikstreaming") + .addChildCriteria( + H11_1, + H11_2, + H11_3, + H11_4 + ) + .build(); + + public static Criterion privateCriterion(String message) { + return privateCriterion(message, 0, 1); + } + + public static Criterion privateCriterion(String message, int max) { + return privateCriterion(message, 0, max); + } + + public static Criterion privateCriterion(String message, int min, int max) { + return Criterion.builder() + .shortDescription(message) + .grader(graderPrivateOnly(max)) + .minPoints(min) + .maxPoints(max) + .build(); + } + + @Override + public Rubric getRubric() { + return RUBRIC; + } +} diff --git a/H11/src/graderPublic/java/h11/H11_Test.java b/H11/src/graderPublic/java/h11/H11_Test.java new file mode 100644 index 0000000..66a70b7 --- /dev/null +++ b/H11/src/graderPublic/java/h11/H11_Test.java @@ -0,0 +1,154 @@ +package h11; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.apache.commons.lang3.stream.Streams; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.provider.Arguments; +import org.sourcegrade.jagr.api.testing.extension.TestCycleResolver; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; +import spoon.reflect.code.CtDo; +import spoon.reflect.code.CtFor; +import spoon.reflect.code.CtForEach; +import spoon.reflect.code.CtWhile; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.emptyContext; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions4.assertIsNotRecursively; + +public class H11_Test { + + public void assertContainsAll(List expected, List actual, Context context) { + assertEquals(expected.size(), actual.size(), context, r -> "List does not contain same amount of items."); + + Context contextComplete = contextBuilder() + .add(context) + .add("actual", actual) + .add("expected", expected) + .build(); + + for (int i = 0; i < expected.size(); i++) { + int finalI = i; + + assertTrue( + expected.stream().anyMatch( + exp -> { + if (exp == null){ + return actual.get(finalI) == null; + } + return exp.equals(actual.get(finalI)); + }), + contextComplete, + r -> "Actual List does not contain all expected Elements. Actual " + finalI + " not found!" + ); + } + } + + public void assertContainsAll(Map expected, Map actual, Context context) { + assertEquals(expected.size(), actual.size(), context, r -> "Map does not contain same amount of items."); + + Context contextComplete = contextBuilder() + .add(context) + .add("actual", actual) + .add("expected", expected) + .build(); + + List> actualEntrys = new ArrayList<>(actual.entrySet()); + for (int i = 0; i < expected.size(); i++) { + int finalI = i; + + Map.Entry actualEntry = actualEntrys.get(i); + + assertTrue( + expected.entrySet().stream().anyMatch( + e -> { + Object key = e.getKey(); + Object value = e.getValue(); + if (!key.equals(actualEntry.getKey())) { + return false; + } + if (value == null) { + return actualEntry.getValue() == null; + } else { + return value.equals(actualEntry.getValue()); + } + }), + contextComplete, + r -> "Actual Map does not contain all expected Elements. Actual " + finalI + " not found!" + ); + } + } + + public void assertListEquals(List expected, List actual, Context context) { + assertEquals(expected.size(), actual.size(), context, r -> "List does not contain same amount of items."); + + Context contextComplete = contextBuilder() + .add(context) + .add("actual", actual) + .add("expected", expected) + .build(); + + for (int i = 0; i < expected.size(); i++) { + int finalI = i; + + boolean equals; + if (expected.get(i) == null) { + equals = actual.get(finalI) == null; + } else { + equals = expected.get(i).equals(actual.get(i)); + } + + assertTrue(equals, contextComplete, r -> "Actual List does not match expected Elements. Actual at " + finalI + " is not the same as expected!"); + } + } + + public void assertNoLoopOrRecursion(Method methodToCheck) { + assertIsNotRecursively(BasicMethodLink.of(methodToCheck).getCtElement(), emptyContext(), r -> "Method %s uses recursion.".formatted(methodToCheck.getName())); + if (BasicMethodLink.of(methodToCheck).getCtElement().getElements(e-> e instanceof CtFor + || e instanceof CtForEach + || e instanceof CtWhile + || e instanceof CtDo).isEmpty()) { + return; + } + Assertions2.fail( + emptyContext(), + r -> "Method %s uses loops.".formatted(methodToCheck.getName()) + ); + } + + public static Stream parseJsonFile(String filename){ + final ArrayNode rootNode; + if (TestCycleResolver.getTestCycle() != null){ + + URL url = H11_Test.class.getResource(filename.replaceFirst(ReflectionUtils.getExercisePrefix(H11_Test.class) + "/", "")); + Assertions.assertNotNull(url, "Could not find JSON file: " + filename); + try { + rootNode = (ArrayNode) new ObjectMapper().readTree(url); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + try { + rootNode = (ArrayNode) new ObjectMapper().readTree(Files.readString(Path.of("src/graderPublic/resources/" + filename))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return Streams.of(rootNode).map(Arguments::of); + + } +} diff --git a/H11/src/graderPublic/java/h11/Invocation.java b/H11/src/graderPublic/java/h11/Invocation.java new file mode 100644 index 0000000..9c6cced --- /dev/null +++ b/H11/src/graderPublic/java/h11/Invocation.java @@ -0,0 +1,24 @@ +package h11; + +import java.util.Arrays; +import java.util.Objects; + +public record Invocation(Object[] arguments, Object returnValue) { + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + Invocation that = (Invocation) object; + return Objects.deepEquals(arguments, that.arguments) && Objects.equals(returnValue, that.returnValue); + } + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(arguments), returnValue); + } +} diff --git a/H11/src/graderPublic/java/h11/JsonConverter.java b/H11/src/graderPublic/java/h11/JsonConverter.java new file mode 100644 index 0000000..0d26eed --- /dev/null +++ b/H11/src/graderPublic/java/h11/JsonConverter.java @@ -0,0 +1,267 @@ +package h11; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import kotlin.Pair; +import org.mockito.stubbing.Answer; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import static h11.ReflectionUtils.actsLikePrimitive; +import static h11.ReflectionUtils.getFieldValue; +import static h11.ReflectionUtils.getSuperClassesIncludingSelf; +import static h11.ReflectionUtils.setFieldValue; +import static org.mockito.Mockito.mock; + +public class JsonConverter { + + public static final ObjectMapper MAPPER = new ObjectMapper(); + + protected Map, Function> typeMapperJSON = new HashMap<>() {{ + put(List.class, (list) -> toJsonNode((List) list)); + put(Map.class, (map) -> toJsonNode((Map) map)); + put(Map.Entry.class, + (entry) -> MAPPER.createArrayNode() + .add(toJsonNode(((Map.Entry) entry).getKey())) + .add(toJsonNode(((Map.Entry) entry).getValue())) + ); + }}; + + protected Map, BiFunction, Object>> typeMapperObject = new HashMap<>() {{ + put(List.class, (node, answer) -> toList(node, answer)); + put(Map.class, (node, answer) -> toMap(node, answer)); + put(Map.Entry.class, + (node, answer) -> Map.entry( + fromJsonNode((ObjectNode) node.get(0), answer), + fromJsonNode((ObjectNode) node.get(1), answer) + ) + ); + }}; + + public List toList(final JsonNode jsonNode, Answer defaultAnswer) { + if (jsonNode instanceof ArrayNode arrayNode && arrayNode.isEmpty()) { + return new ArrayList<>(); + } + return (List) StreamSupport.stream(jsonNode.spliterator(), false) + .map(node -> { + try { + return fromJsonNode((ObjectNode) node, defaultAnswer); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + }) + .collect(Collectors.toCollection(ArrayList::new)); + } + + public Map toMap(final JsonNode jsonNode, Answer defaultAnswer) { + if (jsonNode instanceof ArrayNode arrayNode && arrayNode.isEmpty()) { + return new HashMap<>(); + } + Map returnMap = new HashMap<>(); + StreamSupport.stream(jsonNode.spliterator(), false) + .map(node -> { + try { + Object key = fromJsonNode((ObjectNode) node.get(0), defaultAnswer); + Object value = fromJsonNode((ObjectNode) node.get(1), defaultAnswer); + + return new Pair<>(key, value); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + }) + .forEach(entry -> returnMap.put((K) entry.component1(), (V) entry.component2())); + return returnMap; + } + + public ObjectNode toJsonNode(Object toMap) { + ObjectNode rootNode = MAPPER.createObjectNode(); + + if (toMap == null) { + rootNode.put("type", "null"); + return rootNode; + } + + Class objectClass = toMap.getClass(); + List fields = List.of(objectClass.getDeclaredFields()); + + //test if class is a lambda + if (ReflectionUtils.isLambda(objectClass)) { + rootNode.put("type", objectClass.getInterfaces()[0].getName()); + } else if (ReflectionUtils.isSyntheticMock(objectClass)) { + rootNode.put("type", objectClass.getInterfaces()[0].getName()); + } else { + rootNode.put("type", objectClass.getName()); + } + + + if (toMap.getClass().isArray()) { + toMap = List.of((Object[]) toMap); + } + + if (actsLikePrimitive(toMap.getClass())) { + rootNode.put("value", toMap.toString()); + return rootNode; + } else if (getSuperClassesIncludingSelf(toMap.getClass()).stream().anyMatch(type -> typeMapperJSON.containsKey(type))) { + rootNode.set("value", + typeMapperJSON.get(getSuperClassesIncludingSelf(toMap.getClass()).stream() + .filter(type -> typeMapperJSON.containsKey(type)) + .findFirst() + .orElseThrow()).apply(toMap) + ); + return rootNode; + } + + ArrayNode fieldsJSON = MAPPER.createArrayNode(); + + //Skip fields for mocks + if (!ReflectionUtils.isSyntheticMock(objectClass)) { + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers())) { + continue; + } + ObjectNode fieldJSON = MAPPER.createObjectNode(); + + String name = field.getName(); + Object fieldValue = getFieldValue(toMap, name); + + fieldJSON.put("name", name); + + for (Map.Entry value : toJsonNode(fieldValue).properties()) { + fieldJSON.set(value.getKey(), value.getValue()); + } + + fieldsJSON.add(fieldJSON); + } + } + + rootNode.set("fields", fieldsJSON); + + return rootNode; + } + + public static Class getTypeFromNode(ObjectNode nodeToConvert) { + String className = nodeToConvert.get("type").asText(); + + if (className.equals("null")) { + return null; + } + + try { + return (Class) Class.forName(className); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + public T fromJsonNode(ObjectNode nodeToConvert, Answer defaultAnswer) { + Class objectClass = getTypeFromNode(nodeToConvert); + + if (objectClass == null) { + return null; + } + + //needs to be here for primitive parsing + if (actsLikePrimitive(objectClass)) { + return extractPrimitiveValue(objectClass, nodeToConvert); + } else if (getSuperClassesIncludingSelf(objectClass).stream().anyMatch(type -> typeMapperObject.containsKey(type))) { + return (T) typeMapperObject.get(getSuperClassesIncludingSelf(objectClass).stream() + .filter(type -> typeMapperObject.containsKey(type)) + .findFirst() + .orElseThrow()).apply(nodeToConvert.get("value"), defaultAnswer); + } + + T constructed; + if (defaultAnswer != null) { + constructed = mock(objectClass, defaultAnswer); + } else { + try { + constructed = (T) ReflectionUtils.getUnsafe().allocateInstance(objectClass); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } + } + + for (JsonNode fieldNode : nodeToConvert.get("fields")) { + ObjectNode field = (ObjectNode) fieldNode; + String fieldName = field.get("name").asText(); + + try { + Object fieldValue = fromJsonNode(field, defaultAnswer); + ; + + if (fieldValue != null) { + setFieldValue(constructed, fieldName, fieldValue); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return constructed; + } + + public static T extractPrimitiveValue(Class objectClass, ObjectNode node) { + String value = node.get("value").asText(); + Object fieldValue = null; + + if (String.class == objectClass) { + fieldValue = value; + } else if (boolean.class == objectClass || Boolean.class == objectClass) { + fieldValue = Boolean.parseBoolean(value); + } else if (byte.class == objectClass || Byte.class == objectClass) { + fieldValue = Byte.parseByte(value); + } else if (short.class == objectClass || Short.class == objectClass) { + fieldValue = Short.parseShort(value); + } else if (int.class == objectClass || Integer.class == objectClass) { + fieldValue = Integer.parseInt(value); + } else if (long.class == objectClass || Long.class == objectClass) { + fieldValue = Long.parseLong(value); + } else if (float.class == objectClass || Float.class == objectClass) { + fieldValue = Float.parseFloat(value); + } else if (double.class == objectClass || Double.class == objectClass) { + fieldValue = Double.parseDouble(value); + } else if (char.class == objectClass || Character.class == objectClass) { + fieldValue = value.charAt(0); + } else if (Enum.class.isAssignableFrom(objectClass)) { + try { + return (T) objectClass.getDeclaredMethod("valueOf", String.class).invoke(null, node.get("value").asText()); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + return (T) fieldValue; + } + + public JsonNode toJsonNode(List toMap) { + ArrayNode rootNode = MAPPER.createArrayNode(); + for (Object object : toMap) { + rootNode.add(toJsonNode(object)); + } + return rootNode; + } + + public JsonNode toJsonNode(Map toMap) { + ArrayNode rootNode = MAPPER.createArrayNode(); + for (Map.Entry object : toMap.entrySet()) { + ArrayNode vals = MAPPER.createArrayNode(); + vals.add(toJsonNode(object.getKey())); + vals.add(toJsonNode(object.getValue())); + rootNode.add(vals); + } + return rootNode; + } +} \ No newline at end of file diff --git a/H11/src/graderPublic/java/h11/MockConverter.java b/H11/src/graderPublic/java/h11/MockConverter.java new file mode 100644 index 0000000..8d49043 --- /dev/null +++ b/H11/src/graderPublic/java/h11/MockConverter.java @@ -0,0 +1,597 @@ +package h11; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.google.common.collect.Streams; +import kotlin.Pair; +import org.jetbrains.annotations.NotNull; +import org.mockito.Mockito; +import org.mockito.exceptions.base.MockitoException; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opentest4j.AssertionFailedError; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers; +import org.tudalgo.algoutils.tutor.general.match.MatchingUtils; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static h11.ReflectionUtils.isObjectMethod; +import static org.mockito.Mockito.mock; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.fail; + +public class MockConverter extends JsonConverter { + + public static String SOLUTION_PACKAGE_INFIX = "solution"; + + private static Boolean hasSolution; + private BiMap objects = HashBiMap.create(); + private Map mapped = new HashMap<>(); + private BiMap solutionMocks = HashBiMap.create(); + private boolean remap = false; + + public MockConverter() { + } + + public MockConverter(boolean shouldApplyRemapping) { + remap = shouldApplyRemapping; + } + + @Override + public ObjectNode toJsonNode(Object toMap) { + + int identityHashCode = System.identityHashCode(toMap); + if (mapped.containsKey(identityHashCode)) { + return mapped.get(identityHashCode); + } + if (objects.containsValue(toMap) && ReflectionUtils.actsLikePrimitive(toMap.getClass())) { + return mapped.get(System.identityHashCode(objects.get(objects.inverse().get(toMap)))); + } + + ObjectNode rootNode = super.toJsonNode(toMap); + + if (mapped.containsKey(identityHashCode)) { + return mapped.get(identityHashCode); + } + + rootNode.put("id", objects.size()); + + if (!objects.containsValue(toMap)) { + objects.put(objects.size(), toMap); + } //else { +// throw new IllegalStateException("Could not map object " + toMap + " mush have been created unexpectedly elsewhere"); +// } + mapped.put(identityHashCode, rootNode); + + return rootNode; + } + + @Override + public T fromJsonNode(ObjectNode nodeToConvert, Answer defaultAnswer) { + if (objects.containsKey(nodeToConvert.get("id").asInt())) { + return (T) objects.get(nodeToConvert.get("id").asInt()); + } + + T constructed = super.fromJsonNode(nodeToConvert, defaultAnswer); + if (constructed == null) { + return null; + } + + if (remap) { + Class solClass = getSolution(getTypeFromNode(nodeToConvert)); + + if (solClass != null) { + System.out.println("Replacing %s with %s as solution".formatted(getTypeFromNode(nodeToConvert), solClass)); + String originalType = nodeToConvert.get("type").asText(); + nodeToConvert.put("type", solClass.getName()); + + Pattern valuePattern = Pattern.compile("\"type\":\"%s\"".formatted(originalType)); + + var matcher = valuePattern.matcher(nodeToConvert.toString()); + + StringBuffer remapped = new StringBuffer(); + while (matcher.find()) { + matcher.appendReplacement(remapped, "\"type\":\"" + solClass.getName() + "\""); + } + matcher.appendTail(remapped); + + ObjectNode mockNode; + try { + mockNode = (ObjectNode) MAPPER.readTree(remapped.toString()); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + Object mock = new JsonConverter().fromJsonNode(mockNode, Mockito.CALLS_REAL_METHODS); + + solutionMocks.put(constructed, mock); + } + } + + if (constructed.getClass().getName().contains("sol")) { + throw new RuntimeException("AutoConverter should not create classes from Solution. Use JsonConverter instead."); + } + if (!objects.containsValue(constructed)) { + objects.put(nodeToConvert.get("id").asInt(), constructed); + } //else { +// System.out.println(constructed); +// throw new IllegalStateException("Could not create object " + constructed + " must have been created unexpectedly +// elsewhere"); +// } + + return (T) constructed; + } + + public void reset() { + objects = HashBiMap.create(); + mapped = new HashMap<>(); + solutionMocks = HashBiMap.create(); + } + + public static ObjectNode mapCall(Object objectToCall, Method method, boolean includeObjectMethods, Object... arguments) + throws InvocationTargetException, IllegalAccessException { + MockConverter converter = new MockConverter(); + + Map>> calls = new HashMap<>(); + + AtomicBoolean stopRecordingCalls = new AtomicBoolean(false); + + Answer answer = invocationOnMock -> { + var returnValue = invocationOnMock.callRealMethod(); + if (!stopRecordingCalls.get()) { + calls + .computeIfAbsent(invocationOnMock.getMock(), (m) -> new HashMap<>()) + .computeIfAbsent(invocationOnMock.getMethod(), (m) -> new HashSet<>()) + .add(new Invocation(invocationOnMock.getArguments(), returnValue)); + } + return returnValue; + }; + + Object converted = deepConvertToMocks(objectToCall, answer); + for (int i = 0; i < arguments.length; i++) { + Class argClass = arguments[i].getClass(); + if (ReflectionUtils.isLambda(argClass)) { + Object original = arguments[i]; + arguments[i] = mock( + argClass.getInterfaces()[0], invocationOnMock -> { + var returnValue = invocationOnMock.getMethod().invoke(original, invocationOnMock.getArguments()); + if (!stopRecordingCalls.get()) { + calls + .computeIfAbsent(invocationOnMock.getMock(), (m) -> new HashMap<>()) + .computeIfAbsent(invocationOnMock.getMethod(), (m) -> new HashSet<>()) + .add(new Invocation(invocationOnMock.getArguments(), returnValue)); + } + return returnValue; + } + ); + } else { + Object existingMock = ReflectionUtils.findInFields(arguments[i], converted); + if (existingMock != null) { + arguments[i] = existingMock; + } else { + arguments[i] = deepConvertToMocks(arguments[i], answer); + } + + } + } + + Object expected; + try { + if (!method.getReturnType().equals(void.class)) { + expected = method.invoke(converted, arguments); + } else { + method.invoke(converted, arguments); + expected = converted; + } + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Can not invoke %s on Class %s with parameters of type %s".formatted( + method.getName(), + objectToCall.getClass(), + Arrays.stream(arguments).map(Object::getClass).toList() + ), e + ); + } + + stopRecordingCalls.set(true); + + for (Object argument : arguments) { + converter.toJsonNode(argument); + } + for (Object called : calls.keySet()) { + converter.toJsonNode(called); + } + + ObjectNode rootNode = MAPPER.createObjectNode(); + + converter.setupEntryPoint(arguments, rootNode, converted, objectToCall.getClass(), method); + + converter.setupMethodCalls(method, includeObjectMethods, calls, rootNode); + + converter.setUpObjects(rootNode); + + rootNode.set("expected", new JsonConverter().toJsonNode(expected)); + + return rootNode; + } + + private void setupEntryPoint(Object[] arguments, ObjectNode rootNode, Object converted, Class invokedClass, + Method invokedMethod) { + rootNode.put("invoked", getID(converted)); + String className = invokedClass.getName(); + String methodName = invokedMethod.getName(); + String methodParameters = Arrays.stream(invokedMethod.getParameters()) + .map(Parameter::getType) + .map(Class::getName) + .collect(Collectors.joining(", ")); + rootNode.put("entryPoint", className + "#" + methodName + "(" + methodParameters + ")"); + ArrayNode argumentsJson = MAPPER.createArrayNode(); + for (Object argument : arguments) { + argumentsJson.add(getID(argument)); + } + rootNode.set("arguments", argumentsJson); + } + + private void setUpObjects(ObjectNode rootNode) { + ArrayNode jsonObjects = MAPPER.createArrayNode(); + mapped.values().stream().sorted((a, b) -> -(a.toString().length() - b.toString().length())).forEach(object -> { + if (containsNode(jsonObjects, object)) { + return; + } + jsonObjects.add(object); + }); + + rootNode.set("objects", jsonObjects); + } + + private void setupMethodCalls(Method method, boolean includeObjectMethods, Map>> calls, + ObjectNode rootNode) { + ArrayNode jsonCalls = MAPPER.createArrayNode(); + for (Map.Entry>> called : calls.entrySet()) { + Object invokedObject = called.getKey(); + ObjectNode objectNode = MAPPER.createObjectNode(); + + objectNode.put("id", getID(invokedObject)); + ArrayNode methodCalls = MAPPER.createArrayNode(); + for (Map.Entry> methods : called.getValue().entrySet()) { + ObjectNode methodNode = MAPPER.createObjectNode(); + + if (!includeObjectMethods && isObjectMethod(methods.getKey()) || + (method.getName().equals(methods.getKey().getName()) && + Arrays.equals(method.getParameters(), methods.getKey().getParameters() + ) + ) + ) { + continue; + } + + methodNode.put("methodName", methods.getKey().getName()); + + ArrayNode invocations = MAPPER.createArrayNode(); + + for (Invocation invocation : methods.getValue()) { + ObjectNode invocationNode = MAPPER.createObjectNode(); + + if (getID(invocation.returnValue()) == -1) { + toJsonNode(invocation.returnValue()); + } + invocationNode.put("return", getID(invocation.returnValue())); + + ArrayNode parameters = MAPPER.createArrayNode(); + for (Object parameter : invocation.arguments()) { + if (getID(parameter) == -1) { + toJsonNode(parameter); + } + parameters.add(getID(parameter)); + } + invocationNode.set("parameter", parameters); + + invocations.add(invocationNode); + } + + methodNode.set("invocations", invocations); + + methodCalls.add(methodNode); + } + objectNode.set("methodCalls", methodCalls); + + if (!objectNode.get("methodCalls").isEmpty()) { + jsonCalls.add(objectNode); + } + } + rootNode.set("calls", jsonCalls); + } + + public static Pair recreateCallAndInvoke(ObjectNode node) { + MockConverter converter = new MockConverter(true); + + String[] entryPointString = node.get("entryPoint").asText().split("#"); + String clazz = entryPointString[0]; + String[] method = entryPointString[1].replaceFirst(".$", "").split("\\("); + + Method entryPoint; + try { + entryPoint = Class.forName(clazz).getMethod( + method[0], Arrays.stream(method).skip(1).map(param -> { + try { + return Class.forName(param); + } catch (ClassNotFoundException e) { + return ReflectionUtils.getClassFromPrimitiveString(param); + } + }).toArray(Class[]::new) + ); + } catch (NoSuchMethodException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + + Object invoked = recreateObjectsAndCalls(node, converter, entryPoint); + + Object[] arguments = Streams.stream(node.get("arguments")).map(id -> converter.objects.get(id.asInt())).toArray(); + + return new Pair<>(invoked, new Invocation(arguments, ReflectionUtils.callMethod(invoked, entryPoint, arguments))); + } + + public static T recreateObjectsAndCalls(ObjectNode node, Method entryPoint) { + return recreateObjectsAndCalls(node, new MockConverter(true), entryPoint); + } + + public static T recreateObjectsAndCalls(ObjectNode node, MockConverter converter, Method entryPoint) { + Map>> calls = new HashMap<>(); + + Answer defaultAnswer = converter.createDefaultAnswer(calls, entryPoint); + + converter.createObjects(node, converter, defaultAnswer); + + converter.createCalls(node, calls); + + return (T) converter.objects.get(node.get("invoked").asInt()); + } + + private void createCalls(ObjectNode node, Map>> calls) { + ArrayNode callNode = (ArrayNode) node.get("calls"); + for (JsonNode call : callNode) { + int objectID = call.get("id").asInt(); + Object object = objects.get(objectID); + var objectMap = calls.computeIfAbsent(objectID, (id) -> new HashMap<>()); + + ArrayNode methodNode = (ArrayNode) call.get("methodCalls"); + for (JsonNode method : methodNode) { + Method methodObject = null; + + for (JsonNode invocation : method.get("invocations")) { + ArrayNode parameterNode = (ArrayNode) invocation.get("parameter"); + List parameters = new ArrayList<>(); + + for (JsonNode parameter : parameterNode) { + parameters.add(objects.get(parameter.asInt())); + } + + try { + if (methodObject == null) { + methodObject = ReflectionUtils.getMethodForParameters( + method.get("methodName").asText(), + object.getClass(), + parameters, + false + ); + } + + var methodMap = objectMap.computeIfAbsent(methodObject, (m) -> new ArrayList<>()); + methodMap.add(new Invocation( + parameters.toArray(), + objects.get(invocation.get("return").asInt()) + )); + + } catch (NoSuchMethodException ignored) { + } + } + } + } + } + + private void createObjects(ObjectNode node, MockConverter converter, Answer defaultAnswer) { + ArrayNode objects = (ArrayNode) node.get("objects"); + for (JsonNode object : objects) { + converter.fromJsonNode((ObjectNode) object, defaultAnswer); + } + } + + private @NotNull Answer createDefaultAnswer(Map>> calls, Method entryPoint) { + return (mockInvocation) -> { + + if (mockInvocation.getMethod().equals(entryPoint)) { + return callRealMethod(mockInvocation); + } + + //replace call with call to solution + if (solutionMocks.containsKey(mockInvocation.getMock())) { + return replaceCallWithSolution(mockInvocation); + } + + int objectID = getID(mockInvocation.getMock()); + Map> objectCalls = calls.get(objectID); + + if (objectCalls == null || !objectCalls.containsKey(mockInvocation.getMethod())) { + return callRealMethod(mockInvocation); + } + + List invocations = objectCalls.get(mockInvocation.getMethod()); + Optional invocation = invocations.stream() + .filter((inv) -> Arrays.deepEquals(inv.arguments(), mockInvocation.getArguments())) + .findFirst(); + + if (invocation.isPresent()) { + return invocation.get().returnValue(); + } + + return callRealMethod(mockInvocation); + }; + } + + private Object callRealMethod(InvocationOnMock mockInvocation) { + try { + return mockInvocation.callRealMethod(); + } catch (MockitoException e) { + System.err.println("Tried to call \"" + mockInvocation.getMethod() + "\" on class " + mockInvocation.getMock() + .getClass()); + e.printStackTrace(); + } catch (AssertionFailedError e) { + throw e; + } catch (Throwable e) { + + String stacktrace = Arrays.stream(e.getStackTrace()) + .map(Object::toString) + .takeWhile(s -> !s.contains("java.base") && !s.contains("org.junit.jupiter")) + .collect(Collectors.joining("\n ")); + if (stacktrace.isBlank()) { + stacktrace = Arrays.stream(e.getStackTrace()) + .map(Object::toString) + .takeWhile(s -> !s.contains("org.junit.jupiter")) + .collect(Collectors.joining("\n ")); + } + + Context context = contextBuilder() + .add("Object", mockInvocation.getMock()) + .add("Parameters", Arrays.stream(mockInvocation.getArguments()).map(Object::toString).toList()) + .add("Exception Class", e.getClass()) + .add("Message", e.getMessage()) + .add("Stacktrace", stacktrace) + .build(); + fail(context, r -> "Method " + mockInvocation.getMethod().getName() + "() threw an exception!"); + } + //should never happen here to appease compiler + throw new RuntimeException("fail did not trigger correctly!"); + } + + private Object replaceCallWithSolution(InvocationOnMock mockInvocation) + throws IllegalAccessException, InvocationTargetException { + Object solMock = solutionMocks.get(mockInvocation.getMock()); + + //map all parameters to solution mocks if available + Object[] params = Arrays.stream(mockInvocation.getArguments()) + .map(obj -> { + if (solutionMocks.containsKey(obj)) { + return solutionMocks.get(obj); + } + return obj; + }).toArray(); + + Object returnedObject = null; + try { + returnedObject = + ReflectionUtils.getMethodForParameters(mockInvocation.getMethod().getName(), solMock.getClass(), List.of(params)) + .invoke(solMock, params); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + + //map returned object back to student object + if (solutionMocks.inverse().containsKey(returnedObject)) { + return solutionMocks.inverse().get(returnedObject); + } else { +// boolean needsRemapping = typeMapperJSON.keySet().stream().anyMatch(unMappedClazz -> unMappedClazz +// .isAssignableFrom(returnedObject.getClass())); + + //TODO remapping with newly created solution object and non json mockable classes + } + return returnedObject; + } + + private Integer getID(Object object) { + if (!objects.containsValue(object)) { + return -1; + } + return objects.inverse().get(object); + } + + public static T deepConvertToMocks(T toConvert, Answer defaultAnswer) { + var json = new MockConverter().toJsonNode(toConvert); + return new MockConverter().fromJsonNode(json, defaultAnswer); + } + + @SuppressWarnings("removal") + public static Class getSolution(Class studentClass) { + String classPackageName = studentClass.getPackageName(); + //test if class is even part of exercise + + if (!classPackageName.matches("h\\d\\d(\\.|$).*")) { + return null; + } + + if (hasSolution != null && !hasSolution) { + return null; + } + + Package closestPackage = ReflectionUtils.getAllPackagesInExercise(studentClass).stream() + .min((a, b) -> { + double simA = MatchingUtils.similarity(a.getName(), classPackageName); + double simB = MatchingUtils.similarity(b.getName(), classPackageName); + + if (simA > simB) { + return -1; + } else if (simB > simA) { + return 1; + } + return 0; + } + ).orElse(null); + + if (closestPackage == null) { + return null; + } + + Pattern pattern = Pattern.compile("(?[a-zA-Z0-9]{3})(\\.(?.*))?"); + Matcher matcher = pattern.matcher(closestPackage.getName()); + + //needed for match to work. return may be ignored + matcher.matches(); + + String exercise = matcher.group("exercise") + "."; + + String pack = matcher.group("package") != null ? "." + matcher.group("package") : ""; + + String solutionPackage = exercise + SOLUTION_PACKAGE_INFIX + pack; + + TypeLink + link = BasicPackageLink.of(solutionPackage).getType(BasicStringMatchers.similar(studentClass.getSimpleName(), 0.75)); + if (link == null) { + hasSolution = false; + return null; + } + + return link.reflection(); + } + + public static boolean containsNode(JsonNode object, JsonNode toFind) { + for (JsonNode inner : object) { + if (inner.equals(toFind) || inner.get("id") != null && inner.get("id").asInt() == toFind.get("id").asInt()) { + return true; + } + if (containsNode(inner, toFind)) { + return true; + } + } + return false; + } +} diff --git a/H11/src/graderPublic/java/h11/MusicStreamingTest.java b/H11/src/graderPublic/java/h11/MusicStreamingTest.java new file mode 100644 index 0000000..11d343a --- /dev/null +++ b/H11/src/graderPublic/java/h11/MusicStreamingTest.java @@ -0,0 +1,386 @@ +package h11; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import kotlin.Pair; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; + +import static org.mockito.Mockito.CALLS_REAL_METHODS; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; + +@TestForSubmission +public class MusicStreamingTest extends H11_Test { + + @ParameterizedTest + @MethodSource("provideAdjustPrice_general") + public void testAdjustPrice_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getFirst(), context, r -> "AdjustPrice() did not return the expected value!"); + } + + private static Stream provideAdjustPrice_general() { + return H11_Test.parseJsonFile("h11/MusicStreaming_adjustPrice_general.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideAdjustPrice_zero") + public void testAdjustPrice_zero(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getFirst(), context, r -> "AdjustPrice() did not return the expected value!"); + } + + private static Stream provideAdjustPrice_zero() { + return H11_Test.parseJsonFile("h11/MusicStreaming_adjustPrice_zero.json"); + } + + + @ParameterizedTest + @MethodSource("provideGenerateRandomPlaylist") + public void testGenerateRandomPlaylist(ObjectNode node) throws NoSuchMethodException { + MusicStreaming invoked = MockConverter.recreateObjectsAndCalls(node, MusicStreaming.class.getDeclaredMethod("getRandomSong")); + + Context context = contextBuilder() + .add("invoked", invoked) + .build(); + + doAnswer(CALLS_REAL_METHODS).when(invoked).getRandomSong(); + + Optional returned = invoked.generateRandomPlaylist().skip(10000).findFirst(); + assertTrue(returned.isPresent(), context, r -> "generateRandomPlaylist() does not return infinite stream"); + + verify(invoked, atLeast(5)).getRandomSong(); + + Song newSong = new Song("", 75489); + doReturn(newSong).when(invoked).getRandomSong(); + + assertTrue(invoked.generateRandomPlaylist().limit(10).allMatch(newSong::equals), context, r -> "Objects returned by generateRandomPlaylist() are not selected by getRandomSong()"); + + } + + private static Stream provideGenerateRandomPlaylist() { + return H11_Test.parseJsonFile("h11/MusicStreaming_generateRandomPlaylist.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetAlbumsByGenre") + public void testGetAlbumsByGenre(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((Map) expected, (Map) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAlbumsByGenre() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getAlbumsByGenre.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetAllGenres_general") + public void testGetAllGenres_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllGenres_general() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getAllGenres_general.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetAllGenres_unique") + public void testGetAllGenres_unique(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllGenres_unique() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getAllGenres_unique.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetAllSongs_general") + public void testGetAllSongs_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllSongs_general() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getAllSongs_general.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetAllSongs_unique") + public void testGetAllSongs_unique(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetAllSongs_unique() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getAllSongs_unique.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetArtistPlaytime") + public void testGetArtistPlaytime(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getSecond().returnValue(), context, r -> "GetArtistPlaytime() did not return the expected value!"); + } + + private static Stream provideGetArtistPlaytime() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getArtistPlaytime.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetArtistPlaytimes") + public void testGetArtistPlaytimes(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((Map) expected, (Map) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetArtistPlaytimes() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getArtistPlaytimes.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetGlobalPlayCounts_general") + public void testGetGlobalPlayCounts_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetGlobalPlayCounts_general() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getGlobalPlayCounts_general.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetGlobalPlayCounts_order") + public void testGetGlobalPlayCounts_order(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetGlobalPlayCounts_order() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getGlobalPlayCounts_order.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetMostPlayedArtist_empty") + public void testGetMostPlayedArtist_empty(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getSecond().returnValue(), context, r -> "GetMostPlayedArtist() did not return the expected value!"); + } + + private static Stream provideGetMostPlayedArtist_empty() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getMostPlayedArtist_empty.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetMostPlayedArtist_full") + public void testGetMostPlayedArtist_full(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getSecond().returnValue(), context, r -> "GetMostPlayedArtist() did not return the expected value!"); + } + + private static Stream provideGetMostPlayedArtist_full() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getMostPlayedArtist_full.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetSongsLongerThan_general") + public void testGetSongsLongerThan_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetSongsLongerThan_general() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getSongsLongerThan_general.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetTopPlayedSongsList") + public void testGetTopPlayedSongsList(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .add("actual", actual.getSecond().returnValue()).add( + "expected", expected) + .build(); + + List returnedList = ((List) (actual.getSecond().returnValue())); + assertTrue( + returnedList.size() <= 5, + context, r -> + "Expected getTopPlayedSongsList() to return list of length <= 3. But returned list of length " + + returnedList.size()); + for (int i = 0; i < returnedList.size(); i++) { + int finalI = i; + assertTrue( + returnedList.get(i).matches(".* ?\\(\\d* plays\\)"), + context, r -> + ("getTopPlayedSongsList() returned String that does not match expected pattern at index " + finalI) + "!"); + + }; + } + + private static Stream provideGetTopPlayedSongsList() { + return H11_Test.parseJsonFile("h11/MusicStreaming_getTopPlayedSongsList.json"); + } + + + @ParameterizedTest + @MethodSource("provideSearchSongs") + public void testSearchSongs(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideSearchSongs() { + return H11_Test.parseJsonFile("h11/MusicStreaming_searchSongs.json"); + } + +} diff --git a/H11/src/graderPublic/java/h11/ReflectionUtils.java b/H11/src/graderPublic/java/h11/ReflectionUtils.java new file mode 100644 index 0000000..caa3eaa --- /dev/null +++ b/H11/src/graderPublic/java/h11/ReflectionUtils.java @@ -0,0 +1,416 @@ +package h11; + +import com.google.common.primitives.Primitives; +import org.eclipse.jdt.core.dom.MethodReference; +import org.jetbrains.annotations.NotNull; +import org.mockito.Mockito; +import org.opentest4j.AssertionFailedError; +import org.sourcegrade.jagr.api.testing.extension.TestCycleResolver; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import sun.misc.Unsafe; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.mockito.AdditionalAnswers.delegatesTo; +import static org.mockito.Mockito.mock; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.fail; + +public class ReflectionUtils { + + private static Map> primitiveStrings = Map.of( + "byte", byte.class, + "short", short.class, + "int", int.class, + "long", long.class, + "float", float.class, + "double", double.class, + "char", char.class, + "boolean", boolean.class + ); + + private static Set packages; + + public static void setFieldValue(Object instance, String fieldName, Object value) { + try { + Class objectClass = instance.getClass(); + Field declaredField = objectClass.getDeclaredField(fieldName); + + //best case field in non Final + if (!Modifier.isFinal(declaredField.getModifiers())) { + try { + declaredField.setAccessible(true); + declaredField.set(instance, value); + return; + } catch (Exception ignored) {} + } + + //field has setter + Optional setter = Arrays + .stream(objectClass.getDeclaredMethods()) + .filter( + m -> m.getName().equalsIgnoreCase("set" + fieldName) + ).findFirst(); + if (setter.isPresent()) { + try { + setter.get().invoke(instance, value); + return; + } catch (IllegalAccessException e) { + throw new RuntimeException("Tried to access " + setter.get(), e); + } + + } + + //rely on Unsafe to set value + Unsafe unsafe = getUnsafe(); + + Field theInternalUnsafeField = Unsafe.class.getDeclaredField("theInternalUnsafe"); + theInternalUnsafeField.setAccessible(true); + Object theInternalUnsafe = theInternalUnsafeField.get(null); + + Method offset = Class.forName("jdk.internal.misc.Unsafe").getMethod("objectFieldOffset", Field.class); + unsafe.putBoolean(offset, 12, true); + + switch (value) { + case Boolean val -> unsafe.putBoolean(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Character val -> unsafe.putChar(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Short val -> unsafe.putShort(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Integer val -> unsafe.putInt(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Long val -> unsafe.putLong(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Double val -> unsafe.putDouble(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + case Float val -> unsafe.putFloat(instance, (long) offset.invoke(theInternalUnsafe, declaredField), val); + default -> unsafe.putObject(instance, (long) offset.invoke(theInternalUnsafe, declaredField), value); + } + } catch (IllegalAccessException | NoSuchFieldException | ClassNotFoundException | NoSuchMethodException | + InvocationTargetException ignored) { + } + } + + public static boolean isSyntheticMock(Class clazz){ + return clazz.getName().contains("org.mockito.codegen."); + } + + public static P spyLambda(Class lambdaType, P lambda) { + return (P) mock(lambdaType, delegatesTo(lambda)); + } + + public static Unsafe getUnsafe() { + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + return (Unsafe) unsafeField.get(null); + } catch (IllegalAccessException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + } + + public static T getFieldValue(Object instance, String fieldName) { + Field f; + Class fieldType = null; + try { + f = instance.getClass().getDeclaredField(fieldName); + + try { + f.setAccessible(true); + return (T) f.get(instance); + } catch (Exception ignored) {} + + fieldType = f.getType(); + if (Primitives.isWrapperType(fieldType)){ + fieldType = Primitives.unwrap(fieldType); + } + + Unsafe unsafe = getUnsafe(); + + Field theInternalUnsafeField = Unsafe.class.getDeclaredField("theInternalUnsafe"); + theInternalUnsafeField.setAccessible(true); + Object theInternalUnsafe = theInternalUnsafeField.get(null); + + Method offset = Class.forName("jdk.internal.misc.Unsafe").getMethod("objectFieldOffset", Field.class); + unsafe.putBoolean(offset, 12, true); + + Object fieldValue; + if( boolean.class == fieldType) fieldValue = unsafe.getBoolean(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( byte.class == fieldType) fieldValue = unsafe.getByte(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( short.class == fieldType) fieldValue = unsafe.getShort(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( int.class == fieldType) fieldValue = unsafe.getInt(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( long.class == fieldType) fieldValue = unsafe.getLong(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( float.class == fieldType) fieldValue = unsafe.getFloat(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( double.class == fieldType) fieldValue = unsafe.getDouble(instance, (long) offset.invoke(theInternalUnsafe, f)); + else if( char.class == fieldType) fieldValue = unsafe.getChar(instance, (long) offset.invoke(theInternalUnsafe, f)); + else fieldValue = unsafe.getObject(instance, (long) offset.invoke(theInternalUnsafe, f)); + return (T) fieldValue; + } catch (NoSuchFieldException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException("Could not get value for Field %s(%s) in %s. Please do not access this field.".formatted( + fieldName, + fieldType, + instance.getClass() + ), e); + } + } + + public static void copyFields(Object source, Object dest){ + for (Field f: source.getClass().getDeclaredFields()) { + setFieldValue(dest, f.getName(), getFieldValue(source, f.getName())); + } + } + + public static boolean equalsForMocks(Object a, Object b){ + if (!a.getClass().equals(b.getClass())){ + return false; + } + if (!Mockito.mockingDetails(a).isMock()){ + return a.equals(b); + } else if (!Mockito.mockingDetails(b).isMock()) { + return b.equals(a); + } + for (Field f: a.getClass().getDeclaredFields()) { + + if (!equalsForMocks(getFieldValue(a, f.getName()), getFieldValue(b, f.getName()))){ + return false; + } + } + return true; + } + + public static Object findInFields(Object toFind, Object toFindIn){ + if (actsLikePrimitive(toFindIn.getClass())){ + return null; + } + if (equalsForMocks(toFind, toFindIn)){ + return toFindIn; + } + for (Field f: toFindIn.getClass().getDeclaredFields()) { + if (Modifier.isStatic(f.getModifiers())){ + continue; + } + Object found = findInFields(toFind, getFieldValue(toFindIn, f.getName())); + if (found != null){ + return found; + } + } + return null; + } + + public static Class getClassFromPrimitiveString(String string){ + return primitiveStrings.get(string); + } + + public static boolean actsLikePrimitive(Class type) { + return type.isPrimitive() || + Enum.class.isAssignableFrom(type) || + Primitives.isWrapperType(type) || + type == String.class; + } + + public static List> getSuperClassesIncludingSelf(Class clazz){ + List> classes = new ArrayList<>(); + Deque> classDeque = new ArrayDeque<>(); + + classDeque.add(clazz); + + while ((clazz = classDeque.peekFirst()) != null) { + classDeque.pop(); + + classes.add(clazz); + if (clazz.getSuperclass() != null) { + classDeque.add(clazz.getSuperclass()); + } + if (clazz.getInterfaces().length > 0){ + classDeque.addAll(List.of(clazz.getInterfaces())); + } + + } + return classes; + } + + public static List getAllMethods(Class clazz, boolean includeMockitoSynthetic) { + return getSuperClassesIncludingSelf(clazz).stream() + .filter(c -> includeMockitoSynthetic || !isSyntheticMock(c)) + .flatMap(c -> Stream.of(c.getDeclaredMethods())) + .toList(); + } + + public static boolean isLambda(Class clazz){ + return clazz.isSynthetic() && clazz.getDeclaredMethods().length == 1 && !clazz.getDeclaredMethods()[0].isSynthetic(); + } + + public static boolean isObjectMethod(Method methodToCheck) { + List objectMethods = List.of("getClass", "hashCode", "equals", "clone", "toString", "notify", "notifyAll", "wait", "finalize"); + return objectMethods.contains(methodToCheck.getName()); + } + + public static Object callMethod(Object invoked, Method method, Object... arguments){ + try { + return method.invoke(invoked, arguments); + } catch (IllegalArgumentException | IllegalAccessException e) { + Context context = contextBuilder() + .add("Object", invoked) + .add("Parameters", Arrays.stream(arguments) + .map(o -> o != null ? o.toString() : o) + .toList() + ) + .add("Stacktrace", Arrays.stream(e.getStackTrace()) + .map(Object::toString) + .collect(Collectors.joining("\n ")) + ) + .build(); + fail(context, r -> "Method " + method.getName() + "() can not be accessed or invoked with the supplied arguments!"); + } catch (InvocationTargetException e) { + Throwable cause = e.getCause(); + + if (cause instanceof AssertionFailedError) { + ReflectionUtils.getUnsafe().throwException(cause); + } + + Context context = contextBuilder() + .add("Object", invoked) + .add("Parameters", Arrays.stream(arguments) + .map(o -> o != null ? o.toString() : o) + .toList() + ) + .add("Exception Class", cause.getClass()) + .add("Message", cause.getMessage()) + .add("Stacktrace", Arrays.stream(cause.getStackTrace()) + .map(Object::toString) + .takeWhile(s -> !s.contains("java.base") && !s.contains("org.junit.jupiter")) + .collect(Collectors.joining("\n ")) + ) + .build(); + fail(context, r -> "Method " + method.getName() + "() threw an exception!"); + } + //should never happen here to appease compiler + throw new RuntimeException("fail did not trigger correctly!"); + } + + public static @NotNull Method getMethodForParameters(String methodName, Class clazz, List parameters) throws NoSuchMethodException { + return getMethodForParameters(methodName, clazz, parameters, true); + } + + public static @NotNull Method getMethodForParameters(String methodName, Class clazz, List parameters, boolean includeMockitoSynthetic) throws NoSuchMethodException { + return getAllMethods(clazz, includeMockitoSynthetic).stream() + .filter(m -> m.getName().equals(methodName)) + .filter(m -> { + List> parameterClasses = + parameters.stream().map(Object::getClass).map(Primitives::unwrap).collect(Collectors.toList()); + List> actualParameters = + Arrays.stream(m.getParameters()).map(Parameter::getType).map(Primitives::unwrap).collect(Collectors.toList()); + + Map, Integer> occurrencesActual = + actualParameters.stream().collect(Collectors.groupingBy( + obj -> obj, + Collectors.summingInt(obj -> 1) + )); + Map, Integer> occurrencesExpected = + parameterClasses.stream().collect(Collectors.groupingBy( + obj -> obj == null ? MethodReference.class : obj, + Collectors.summingInt(obj -> 1) + )); + + boolean hasCorrectParams = parameterClasses.stream().allMatch( + param -> actualParameters.stream().anyMatch( + actualParam -> param == null || (actualParam.isAssignableFrom(param) + && occurrencesActual.getOrDefault(actualParam, 0) + >= occurrencesExpected.getOrDefault(param, 0)) + ) + ); + return parameters.size() == actualParameters.size() && hasCorrectParams; + } + ) + .findFirst() + .orElseThrow(() -> { + String methodsWithSameName = getAllMethods(clazz, false).stream().filter(m -> m.getName().equals(methodName)).map(Objects::toString).collect( + Collectors.joining("\n")); + if (methodsWithSameName.isBlank()){ + methodsWithSameName = "None"; + } + return new NoSuchMethodException("Could not find method " + methodName + " with parameters " + parameters.stream().map(Object::getClass).map(Primitives::unwrap).toList() + ". Methods with same name:\n" + methodsWithSameName); + }); + } + + public static Set getAllPackagesInExercise(Class classInExercise){ + if (packages != null) { + return packages; + } + + if (TestCycleResolver.getTestCycle() == null){ + String dir = null; + try { + dir = new File(classInExercise.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParent(); + } catch (URISyntaxException e2) { + e2.printStackTrace(); + } + + try (Stream<@NotNull Path> paths = Files.walk(Paths.get(dir))){ + + Set packages = paths.toList().stream() + .map(Objects::toString) + .filter(path -> path.contains("java/main/") && path.endsWith(".class")) + .map(path -> path.split("java/main/")[1]) + .map(path -> path.substring(0, path.lastIndexOf(File.separator))) + .collect(Collectors.toSet()) + .stream() + .map(packageName -> classInExercise.getClassLoader().getDefinedPackage(packageName)) + .collect(Collectors.toSet()); + + ReflectionUtils.packages = packages; + + final var resourcePath = "src/graderPublic/resources/packages.txt"; + File file = new File(resourcePath); + file.getParentFile().mkdirs(); + file.createNewFile(); + + Files.writeString(file.toPath(), packages.stream().map(Package::getName).collect(Collectors.joining("\n"))); + + return packages; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + try { + Set packages = Files.readAllLines(Path.of("src/graderPublic/resources/packages.txt")).stream() + .map(packageName -> classInExercise.getClassLoader().getDefinedPackage(packageName)) + .collect(Collectors.toSet()); + ReflectionUtils.packages = packages; + + return packages; + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + + public static String getExercisePrefix(Class classInExercise){ + Pattern pattern = Pattern.compile("^(?[a-zA-Z0-9]{3})\\..*"); + Matcher matcher = pattern.matcher(classInExercise.getName()); + + //needed for match to work. return may be ignored + matcher.matches(); + + return matcher.group("exercise"); + } +} diff --git a/H11/src/graderPublic/java/h11/SongTest.java b/H11/src/graderPublic/java/h11/SongTest.java new file mode 100644 index 0000000..6ec7ccd --- /dev/null +++ b/H11/src/graderPublic/java/h11/SongTest.java @@ -0,0 +1,37 @@ +package h11; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import kotlin.Pair; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; + +@TestForSubmission +public class SongTest { + + @ParameterizedTest + @MethodSource("provideIsLongerThan") + public void testIsLongerThan(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getSecond().returnValue(), context, r -> "IsLongerThan() did not return the expected value!"); + } + + private static Stream provideIsLongerThan() { + return H11_Test.parseJsonFile("h11/Song_isLongerThan.json"); + } + +} diff --git a/H11/src/graderPublic/java/h11/UserTest.java b/H11/src/graderPublic/java/h11/UserTest.java new file mode 100644 index 0000000..1f92f21 --- /dev/null +++ b/H11/src/graderPublic/java/h11/UserTest.java @@ -0,0 +1,195 @@ +package h11; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import kotlin.Pair; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder; + +@TestForSubmission +public class UserTest extends H11_Test { + + @ParameterizedTest + @MethodSource("provideGetPlayCounts_return") + public void testGetPlayCounts_return(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetPlayCounts_return() { + return H11_Test.parseJsonFile("h11/User_getPlayCounts_return.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetTopPlayedSongsList_formatting") + public void testGetTopPlayedSongsList_formatting(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .add("actual", actual.getSecond().returnValue()).add( + "expected", expected) + .build(); + + List returnedList = ((List) (actual.getSecond().returnValue())); + for (int i = 0; i < returnedList.size(); i++) { + int finalI = i; + assertTrue( + returnedList.get(i).matches(".* \\(\\d* plays\\)"), + context, r -> + ("getTopPlayedSongsList() returned String that does not match expected pattern at index " + finalI) + "!"); + + }; + } + + private static Stream provideGetTopPlayedSongsList_formatting() { + return H11_Test.parseJsonFile("h11/User_getTopPlayedSongsList_formatting.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetFavoriteSong_full") + public void testGetFavoriteSong_full(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getSecond().returnValue(), context, r -> "GetFavoriteSong() did not return the expected value!"); + } + + private static Stream provideGetFavoriteSong_full() { + return H11_Test.parseJsonFile("h11/User_getFavoriteSong_full.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetTopPlayedSongsList_size") + public void testGetTopPlayedSongsList_size(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .add("actual", actual.getSecond().returnValue()).add( + "expected", expected) + .build(); + + List returnedList = ((List) (actual.getSecond().returnValue())); + assertTrue( + returnedList.size() <= 3, + context, r -> + "Expected getTopPlayedSongsList() to return list of length <= 3. But returned list of length " + + returnedList.size()); + } + + private static Stream provideGetTopPlayedSongsList_size() { + return H11_Test.parseJsonFile("h11/User_getTopPlayedSongsList_size.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetPlayedSongs_general") + public void testGetPlayedSongs_general(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetPlayedSongs_general() { + return H11_Test.parseJsonFile("h11/User_getPlayedSongs_general.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetPlayCounts_order") + public void testGetPlayCounts_order(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertListEquals((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetPlayCounts_order() { + return H11_Test.parseJsonFile("h11/User_getPlayCounts_order.json"); + } + + + @Disabled + @ParameterizedTest + @MethodSource("provideGetFavoriteSong_empty") + public void testGetFavoriteSong_empty(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + Assertions2.assertEquals(expected, actual.getSecond().returnValue(), context, r -> "GetFavoriteSong() did not return the expected value!"); + } + + private static Stream provideGetFavoriteSong_empty() { + return H11_Test.parseJsonFile("h11/User_getFavoriteSong_empty.json"); + } + + + @ParameterizedTest + @MethodSource("provideGetPlayedSongs_unique") + public void testGetPlayedSongs_unique(ObjectNode node) { + Object expected = new JsonConverter().fromJsonNode((ObjectNode) node.get("expected"), null); + Pair actual = MockConverter.recreateCallAndInvoke(node); + + Context context = contextBuilder() + .add("invoked", actual.getFirst()) + .add("parameters", actual.getSecond().arguments()) + .build(); + + assertContainsAll((List) expected, (List) actual.getSecond().returnValue(), context); + } + + private static Stream provideGetPlayedSongs_unique() { + return H11_Test.parseJsonFile("h11/User_getPlayedSongs_unique.json"); + } + +} diff --git a/H11/src/graderPublic/resources/h11/Album_getAverageDuration_empty.json b/H11/src/graderPublic/resources/h11/Album_getAverageDuration_empty.json new file mode 100644 index 0000000..ff72e95 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Album_getAverageDuration_empty.json @@ -0,0 +1,30 @@ +[ { + "invoked" : 3, + "entryPoint" : "h11.Album#getAverageDuration()", + "arguments" : [ ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 3", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "KPOP", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 3 + } ], + "expected" : { + "type" : "java.lang.Double", + "value" : "0.0" + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/Album_getAverageDuration_full.json b/H11/src/graderPublic/resources/h11/Album_getAverageDuration_full.json new file mode 100644 index 0000000..0ae6787 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Album_getAverageDuration_full.json @@ -0,0 +1,517 @@ +[ { + "invoked" : 18, + "entryPoint" : "h11.Album#getAverageDuration()", + "arguments" : [ ], + "calls" : [ { + "id" : 16, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 15, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 13, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 12, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 10, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 9, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 7, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 6, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 4, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 3, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 4", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "OTHER", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + } ], + "id" : 17 + } ], + "id" : 18 + } ], + "expected" : { + "type" : "java.lang.Double", + "value" : "200.0" + } +}, { + "invoked" : 15, + "entryPoint" : "h11.Album#getAverageDuration()", + "arguments" : [ ], + "calls" : [ { + "id" : 2, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 5, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 4, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 8, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 7, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 13, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 12, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 5", + "id" : 9 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "KPOP", + "id" : 10 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 1 + } ], + "id" : 2 + } ], + "id" : 14 + } ], + "id" : 15 + } ], + "expected" : { + "type" : "java.lang.Double", + "value" : "250.0" + } +}, { + "invoked" : 21, + "entryPoint" : "h11.Album#getAverageDuration()", + "arguments" : [ ], + "calls" : [ { + "id" : 2, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 5, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 4, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 8, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 7, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 11, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 10, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 19, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 18, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 16, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 15, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 12 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ELECTRONIC", + "id" : 13 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 18 + } ], + "id" : 19 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 18 + } ], + "id" : 19 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 4 + } ], + "id" : 5 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "expected" : { + "type" : "java.lang.Double", + "value" : "250.0" + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/Album_getSongsLongerThan.json b/H11/src/graderPublic/resources/h11/Album_getSongsLongerThan.json new file mode 100644 index 0000000..48df32e --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Album_getSongsLongerThan.json @@ -0,0 +1,533 @@ +[ { + "invoked" : 21, + "entryPoint" : "h11.Album#getSongsLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 3, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 22, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 6, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 22, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 8, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 23, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 11, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 23, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 14, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 23, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 19, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 22, + "parameter" : [ 0 ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 15 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "DANCE", + "id" : 16 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 0 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 4 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 2 + } ], + "id" : 3 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + }, { + "type" : "java.lang.Boolean", + "value" : "false", + "id" : 23 + }, { + "type" : "java.lang.Boolean", + "value" : "true", + "id" : 22 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + } ] + } +}, { + "invoked" : 13, + "entryPoint" : "h11.Album#getSongsLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 3, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 14, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 11, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 14, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 8, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 14, + "parameter" : [ 0 ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 2", + "id" : 4 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 5 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 2 + } ], + "id" : 3 + } ], + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "java.lang.Boolean", + "value" : "true", + "id" : 14 + }, { + "type" : "java.lang.Integer", + "value" : "0", + "id" : 0 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + } ] + } +}, { + "invoked" : 4, + "entryPoint" : "h11.Album#getSongsLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 3", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ROCK", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "java.lang.Integer", + "value" : "100", + "id" : 0 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +}, { + "invoked" : 19, + "entryPoint" : "h11.Album#getSongsLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 8, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 20, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 11, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 20, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 5, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 20, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 14, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 20, + "parameter" : [ 0 ] + } ] + } ] + }, { + "id" : 17, + "methodCalls" : [ { + "methodName" : "isLongerThan", + "invocations" : [ { + "return" : 20, + "parameter" : [ 0 ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 4", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "RAP", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + } ], + "id" : 18 + } ], + "id" : 19 + }, { + "type" : "java.lang.Boolean", + "value" : "false", + "id" : 20 + }, { + "type" : "java.lang.Integer", + "value" : "1000", + "id" : 0 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/Artist_getAllGenres_general.json b/H11/src/graderPublic/resources/h11/Artist_getAllGenres_general.json new file mode 100644 index 0000000..359bdff --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Artist_getAllGenres_general.json @@ -0,0 +1,370 @@ +[ { + "invoked" : 30, + "entryPoint" : "h11.Artist#getAllGenres()", + "arguments" : [ ], + "calls" : [ { + "id" : 22, + "methodCalls" : [ { + "methodName" : "genre", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 28, + "methodCalls" : [ { + "methodName" : "genre", + "invocations" : [ { + "return" : 27, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 25, + "methodCalls" : [ { + "methodName" : "genre", + "invocations" : [ { + "return" : 24, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 7", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 8", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 9", + "id" : 23 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "COUNTRY", + "id" : 24 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 25 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 10", + "id" : 26 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "DANCE", + "id" : 27 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 28 + } ], + "id" : 29 + } ], + "id" : 30 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Genre", + "value" : "ALTERNATIVE" + }, { + "type" : "h11.Genre", + "value" : "COUNTRY" + }, { + "type" : "h11.Genre", + "value" : "DANCE" + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/Artist_getAllGenres_unique.json b/H11/src/graderPublic/resources/h11/Artist_getAllGenres_unique.json new file mode 100644 index 0000000..fcbb612 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Artist_getAllGenres_unique.json @@ -0,0 +1,252 @@ +[ { + "invoked" : 26, + "entryPoint" : "h11.Artist#getAllGenres()", + "arguments" : [ ], + "calls" : [ { + "id" : 21, + "methodCalls" : [ { + "methodName" : "genre", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 23, + "methodCalls" : [ { + "methodName" : "genre", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 6", + "id" : 24 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 7", + "id" : 22 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 23 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 8", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 25 + } ], + "id" : 26 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Genre", + "value" : "ALTERNATIVE" + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/Artist_getAllSongs.json b/H11/src/graderPublic/resources/h11/Artist_getAllSongs.json new file mode 100644 index 0000000..a65ca83 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Artist_getAllSongs.json @@ -0,0 +1,1064 @@ +[ { + "invoked" : 24, + "entryPoint" : "h11.Artist#getAllSongs()", + "arguments" : [ ], + "calls" : [ { + "id" : 21, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 20, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 1", + "id" : 22 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "DANCE", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 23 + } ], + "id" : 24 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + } ] + } +}, { + "invoked" : 2, + "entryPoint" : "h11.Artist#getAllSongs()", + "arguments" : [ ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 2", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + } ], + "id" : 2 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +}, { + "invoked" : 22, + "entryPoint" : "h11.Artist#getAllSongs()", + "arguments" : [ ], + "calls" : [ { + "id" : 20, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 19, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 4, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 3, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 3", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 3", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "POP", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 5", + "id" : 5 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "HIPHOP", + "id" : 6 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 8 + } ], + "id" : 9 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 10 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 16 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 17 + } ], + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + } ] + } +}, { + "invoked" : 24, + "entryPoint" : "h11.Artist#getAllSongs()", + "arguments" : [ ], + "calls" : [ { + "id" : 21, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 20, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4", + "id" : 22 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "HIPHOP", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 23 + } ], + "id" : 24 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + } ] + } +}, { + "invoked" : 28, + "entryPoint" : "h11.Artist#getAllSongs()", + "arguments" : [ ], + "calls" : [ { + "id" : 21, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 20, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 25, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 24, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 5", + "id" : 26 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "DANCE", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 11 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 17 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 2", + "id" : 22 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 23 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 6 + } ], + "id" : 7 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 8 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 9 + } ], + "id" : 10 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 27 + } ], + "id" : 28 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/MusicStreaming_adjustPrice_general.json b/H11/src/graderPublic/resources/h11/MusicStreaming_adjustPrice_general.json new file mode 100644 index 0000000..70809c3 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/MusicStreaming_adjustPrice_general.json @@ -0,0 +1,615 @@ +[ { + "invoked" : 2, + "entryPoint" : "h11.MusicStreaming#adjustPrice(double)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "java.lang.Double", + "value" : "0.5", + "id" : 0 + } ], + "expected" : { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ] + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + } +}, { + "invoked" : 12, + "entryPoint" : "h11.MusicStreaming#adjustPrice(double)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 4, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 13, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ 2 ] + } ] + } ] + }, { + "id" : 7, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 15, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ 6 ] + } ] + } ] + }, { + "id" : 10, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 9, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ 9 ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 0", + "id" : 8 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 9 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 10 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 5", + "id" : 5 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "7.5", + "id" : 6 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 7 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 10", + "id" : 1 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "15.0", + "id" : 2 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "java.lang.Double", + "value" : "10.0", + "id" : 13 + }, { + "type" : "java.lang.Double", + "value" : "5.0", + "id" : 15 + }, { + "type" : "java.lang.Double", + "value" : "0.5", + "id" : 0 + }, { + "type" : "null", + "id" : 14 + } ], + "expected" : { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ] + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 0" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 5" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "7.5" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 10" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "15.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + } ] + } ] + } +}, { + "invoked" : 12, + "entryPoint" : "h11.MusicStreaming#adjustPrice(double)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 4, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 13, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ 2 ] + } ] + } ] + }, { + "id" : 10, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 15, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ 9 ] + } ] + } ] + }, { + "id" : 7, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 6, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ 6 ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 0", + "id" : 5 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 6 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 7 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 5", + "id" : 1 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "30.0", + "id" : 2 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 10", + "id" : 8 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "60.0", + "id" : 9 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 10 + } ], + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "java.lang.Double", + "value" : "10.0", + "id" : 15 + }, { + "type" : "java.lang.Double", + "value" : "5.0", + "id" : 13 + }, { + "type" : "java.lang.Integer", + "value" : "5", + "id" : 0 + }, { + "type" : "null", + "id" : 14 + } ], + "expected" : { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ] + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 0" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 5" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "30.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 10" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "60.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + } ] + } ] + } +}, { + "invoked" : 12, + "entryPoint" : "h11.MusicStreaming#adjustPrice(double)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 4, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 13, + "parameter" : [ 2 ] + } ] + } ] + }, { + "id" : 10, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 14, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 13, + "parameter" : [ 9 ] + } ] + } ] + }, { + "id" : 7, + "methodCalls" : [ { + "methodName" : "getPricePerMonth", + "invocations" : [ { + "return" : 9, + "parameter" : [ ] + } ] + }, { + "methodName" : "setPricePerMonth", + "invocations" : [ { + "return" : 13, + "parameter" : [ 6 ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 0", + "id" : 1 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 2 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 5", + "id" : 5 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "2.5", + "id" : 6 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 7 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 10", + "id" : 8 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "5.0", + "id" : 9 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 10 + } ], + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "java.lang.Double", + "value" : "10.0", + "id" : 14 + }, { + "type" : "java.lang.Double", + "value" : "-0.5", + "id" : 0 + }, { + "type" : "null", + "id" : 13 + } ], + "expected" : { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ] + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 0" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 5" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "2.5" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "Username 10" + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "5.0" + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ] + } ] + } ] + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/MusicStreaming_generateRandomPlaylist.json b/H11/src/graderPublic/resources/h11/MusicStreaming_generateRandomPlaylist.json new file mode 100644 index 0000000..726ce32 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/MusicStreaming_generateRandomPlaylist.json @@ -0,0 +1,653 @@ +[ { + "invoked" : 38, + "entryPoint" : "h11.MusicStreaming#generateRandomPlaylist()", + "arguments" : [ ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 6", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 7", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 8", + "id" : 23 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 26 + }, { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 7", + "id" : 27 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 8", + "id" : 23 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 24 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 9", + "id" : 28 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "COUNTRY", + "id" : 29 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 30 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 10", + "id" : 31 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "DANCE", + "id" : 32 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 33 + } ], + "id" : 34 + } ], + "id" : 35 + } ], + "id" : 36 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 37 + } ], + "id" : 38 + } ], + "expected" : { + "type" : "java.util.stream.ReferencePipeline$Head", + "fields" : [ ] + } +}, { + "invoked" : 14, + "entryPoint" : "h11.MusicStreaming#generateRandomPlaylist()", + "arguments" : [ ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 5 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 6 + } ], + "id" : 7 + } ], + "id" : 8 + } ], + "id" : 9 + } ], + "id" : 10 + } ], + "id" : 11 + } ], + "id" : 12 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 13 + } ], + "id" : 14 + } ], + "expected" : { + "type" : "java.util.stream.ReferencePipeline$Head", + "fields" : [ ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/MusicStreaming_getGlobalPlayCounts_general.json b/H11/src/graderPublic/resources/h11/MusicStreaming_getGlobalPlayCounts_general.json new file mode 100644 index 0000000..787c22e --- /dev/null +++ b/H11/src/graderPublic/resources/h11/MusicStreaming_getGlobalPlayCounts_general.json @@ -0,0 +1,245 @@ +[ { + "invoked" : 29, + "entryPoint" : "h11.MusicStreaming#getGlobalPlayCounts()", + "arguments" : [ ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "artist", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 7", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 8", + "id" : 23 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 26 + } ], + "id" : 27 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 28 + } ], + "id" : 29 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_empty.json b/H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_empty.json new file mode 100644 index 0000000..25ae844 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_empty.json @@ -0,0 +1,262 @@ +[ { + "invoked" : 1, + "entryPoint" : "h11.MusicStreaming#getMostPlayedArtist()", + "arguments" : [ ], + "calls" : [ { + "id" : 1, + "methodCalls" : [ { + "methodName" : "getArtistPlaytimes", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 0 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 0 + } ], + "id" : 1 + }, { + "type" : "java.util.HashMap", + "value" : [ ], + "id" : 2 + } ], + "expected" : { + "type" : "null" + } +}, { + "invoked" : 4, + "entryPoint" : "h11.MusicStreaming#getMostPlayedArtist()", + "arguments" : [ ], + "calls" : [ { + "id" : 2, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 4, + "methodCalls" : [ { + "methodName" : "getArtistPlaytimes", + "invocations" : [ { + "return" : 6, + "parameter" : [ ] + } ] + }, { + "methodName" : "getArtistPlaytime", + "invocations" : [ { + "return" : 5, + "parameter" : [ 2 ] + } ] + }, { + "methodName" : "getGlobalPlayCounts", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + } ], + "id" : 2 + } ], + "id" : 3 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + } ], + "id" : 4 + }, { + "type" : "java.util.HashMap", + "value" : [ [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + } ] ], + "id" : 6 + } ], + "expected" : { + "type" : "null" + } +}, { + "invoked" : 7, + "entryPoint" : "h11.MusicStreaming#getMostPlayedArtist()", + "arguments" : [ ], + "calls" : [ { + "id" : 3, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 7, + "methodCalls" : [ { + "methodName" : "getArtistPlaytimes", + "invocations" : [ { + "return" : 9, + "parameter" : [ ] + } ] + }, { + "methodName" : "getArtistPlaytime", + "invocations" : [ { + "return" : 8, + "parameter" : [ 5 ] + } ] + }, { + "methodName" : "getGlobalPlayCounts", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 5, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 5 + } ], + "id" : 6 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 7 + }, { + "type" : "java.util.HashMap", + "value" : [ [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "ALTERNATIVE", + "id" : 1 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "java.lang.Long", + "value" : "0", + "id" : 8 + } ] ], + "id" : 9 + } ], + "expected" : { + "type" : "null" + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_full.json b/H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_full.json new file mode 100644 index 0000000..1e52cd3 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/MusicStreaming_getMostPlayedArtist_full.json @@ -0,0 +1,3317 @@ +[ { + "invoked" : 58, + "entryPoint" : "h11.MusicStreaming#getMostPlayedArtist()", + "arguments" : [ ], + "calls" : [ { + "id" : 6, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 15, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 61, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 31, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 30, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 2, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 0, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 33, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 26, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 13, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 11, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 35, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 63, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 58, + "methodCalls" : [ { + "methodName" : "getArtistPlaytimes", + "invocations" : [ { + "return" : 65, + "parameter" : [ ] + } ] + }, { + "methodName" : "getArtistPlaytime", + "invocations" : [ { + "return" : 64, + "parameter" : [ 38 ] + }, { + "return" : 3, + "parameter" : [ 41 ] + } ] + }, { + "methodName" : "getGlobalPlayCounts", + "invocations" : [ { + "return" : 70, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 56, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 71, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 29, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 28, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 27, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 41, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 40, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 23, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 21, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 44, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 20, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 54, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 29, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 48, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 23, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 38, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 30, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 11, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 10, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 9, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 26, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 25, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 24, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 46, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 72, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 52, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 73, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 20, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 19, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 18, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 50, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 74, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 1", + "id" : 36 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 16 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "OTHER", + "id" : 17 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 19 + } ], + "id" : 20 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 21 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 22 + } ], + "id" : 23 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 24 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 25 + } ], + "id" : 26 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 27 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 28 + } ], + "id" : 29 + } ], + "id" : 30 + } ], + "id" : 31 + } ], + "id" : 37 + } ], + "id" : 38 + }, { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 2", + "id" : 39 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 40 + } ], + "id" : 41 + } ], + "id" : 42 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 19 + } ], + "id" : 20 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 43 + } ], + "id" : 44 + } ], + "id" : 45 + } ], + "id" : 46 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 10 + } ], + "id" : 11 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 12 + } ], + "id" : 13 + } ], + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 21 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 22 + } ], + "id" : 23 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 47 + } ], + "id" : 48 + } ], + "id" : 49 + } ], + "id" : 50 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 1 + } ], + "id" : 2 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 5 + } ], + "id" : 6 + } ], + "id" : 51 + } ], + "id" : 52 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 24 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 25 + } ], + "id" : 26 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 32 + } ], + "id" : 33 + } ], + "id" : 34 + } ], + "id" : 35 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 27 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 28 + } ], + "id" : 29 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 53 + } ], + "id" : 54 + } ], + "id" : 55 + } ], + "id" : 56 + } ], + "id" : 57 + } ], + "id" : 58 + }, { + "type" : "java.util.HashMap", + "value" : [ [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 2", + "id" : 39 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 40 + } ], + "id" : 41 + }, { + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + } ], [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 1", + "id" : 36 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 16 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "OTHER", + "id" : 17 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 19 + } ], + "id" : 20 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 21 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 22 + } ], + "id" : 23 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 24 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 25 + } ], + "id" : 26 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 27 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 28 + } ], + "id" : 29 + } ], + "id" : 30 + } ], + "id" : 31 + } ], + "id" : 37 + } ], + "id" : 38 + }, { + "type" : "java.lang.Long", + "value" : "1500", + "id" : 64 + } ] ], + "id" : 65 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 19 + } ], + "id" : 20 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 66 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 67 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 21 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 22 + } ], + "id" : 23 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 67 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 68 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 24 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 25 + } ], + "id" : 26 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 69 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 27 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 28 + } ], + "id" : 29 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 69 + } ], + "id" : 70 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 27 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 28 + } ], + "id" : 29 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 71 + } ], + "id" : 71 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 19 + } ], + "id" : 20 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 72 + } ], + "id" : 72 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 21 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 22 + } ], + "id" : 23 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 74 + } ], + "id" : 74 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 60 + } ], + "id" : 61 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 24 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 25 + } ], + "id" : 26 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 62 + } ], + "id" : 63 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 59 + } ], + "id" : 73 + } ], + "id" : 73 + } ], + "expected" : { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 1" + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1" + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "OTHER" + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + } ] + } ] + } ] + } ] + } +}, { + "invoked" : 72, + "entryPoint" : "h11.MusicStreaming#getMostPlayedArtist()", + "arguments" : [ ], + "calls" : [ { + "id" : 12, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 75, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 19, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 78, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 28, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 80, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 10, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 4, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 17, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 15, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 35, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 82, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 45, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 44, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 51, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 84, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 22, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 21, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 20, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 15, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 14, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 13, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 72, + "methodCalls" : [ { + "methodName" : "getArtistPlaytimes", + "invocations" : [ { + "return" : 87, + "parameter" : [ ] + } ] + }, { + "methodName" : "getArtistPlaytime", + "invocations" : [ { + "return" : 86, + "parameter" : [ 62 ] + }, { + "return" : 85, + "parameter" : [ 65 ] + } ] + }, { + "methodName" : "getGlobalPlayCounts", + "invocations" : [ { + "return" : 89, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 43, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 42, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 41, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 65, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 44, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 24, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 47, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 43, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 4, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 3, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 70, + "methodCalls" : [ { + "methodName" : "getPlayCounts", + "invocations" : [ { + "return" : 90, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 33, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 31, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 8, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 4, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 40, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 39, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 38, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 62, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 91, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 56, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 55, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 31, + "methodCalls" : [ { + "methodName" : "durationInSeconds", + "invocations" : [ { + "return" : 30, + "parameter" : [ ] + } ] + }, { + "methodName" : "title", + "invocations" : [ { + "return" : 29, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 60, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 59, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 49, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 43, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 26, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 68, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 40, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 5", + "id" : 52 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 53 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "OTHER", + "id" : 54 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + } ], + "id" : 55 + } ], + "id" : 56 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 2", + "id" : 57 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "RAP", + "id" : 58 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 59 + } ], + "id" : 60 + } ], + "id" : 61 + } ], + "id" : 62 + }, { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4", + "id" : 63 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 36 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 37 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + } ], + "id" : 44 + } ], + "id" : 45 + } ], + "id" : 64 + } ], + "id" : 65 + } ], + "id" : 66 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 23 + } ], + "id" : 24 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 25 + } ], + "id" : 26 + } ], + "id" : 27 + } ], + "id" : 28 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 67 + } ], + "id" : 68 + } ], + "id" : 69 + } ], + "id" : 70 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 9 + } ], + "id" : 10 + } ], + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 32 + } ], + "id" : 33 + } ], + "id" : 34 + } ], + "id" : 35 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 46 + } ], + "id" : 47 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 48 + } ], + "id" : 49 + } ], + "id" : 50 + } ], + "id" : 51 + }, { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 5 + }, { + "name" : "cdate", + "type" : "null", + "id" : 6 + } ], + "id" : 16 + } ], + "id" : 17 + } ], + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 71 + } ], + "id" : 72 + }, { + "type" : "java.util.HashMap", + "value" : [ [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4", + "id" : 63 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 36 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 37 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + } ], + "id" : 44 + } ], + "id" : 45 + } ], + "id" : 64 + } ], + "id" : 65 + }, { + "type" : "java.lang.Long", + "value" : "3800", + "id" : 85 + } ], [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 5", + "id" : 52 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 1", + "id" : 53 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "OTHER", + "id" : 54 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + } ], + "id" : 55 + } ], + "id" : 56 + }, { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 2", + "id" : 57 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "RAP", + "id" : 58 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 59 + } ], + "id" : 60 + } ], + "id" : 61 + } ], + "id" : 62 + }, { + "type" : "java.lang.Long", + "value" : "2900", + "id" : 86 + } ] ], + "id" : 87 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "java.lang.Long", + "value" : "2", + "id" : 73 + } ], + "id" : 88 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "java.lang.Long", + "value" : "2", + "id" : 73 + } ], + "id" : 88 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "java.lang.Long", + "value" : "2", + "id" : 73 + } ], + "id" : 88 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 76 + } ], + "id" : 88 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 76 + } ], + "id" : 89 + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 76 + } ], + "id" : 89 + } ], + "id" : 89 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 91 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 29 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 30 + } ], + "id" : 31 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 76 + } ], + "id" : 81 + } ], + "id" : 82 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 76 + } ], + "id" : 77 + } ], + "id" : 78 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 38 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 39 + } ], + "id" : 40 + }, { + "type" : "java.lang.Long", + "value" : "1", + "id" : 76 + } ], + "id" : 90 + } ], + "id" : 90 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 20 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 21 + } ], + "id" : 22 + }, { + "type" : "java.lang.Long", + "value" : "2", + "id" : 73 + } ], + "id" : 79 + } ], + "id" : 80 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 41 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 42 + } ], + "id" : 43 + }, { + "type" : "java.lang.Long", + "value" : "2", + "id" : 73 + } ], + "id" : 83 + } ], + "id" : 84 + }, { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 2 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 3 + } ], + "id" : 4 + }, { + "type" : "java.lang.Long", + "value" : "2", + "id" : 73 + } ], + "id" : 74 + } ], + "id" : 75 + } ], + "expected" : { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4" + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6" + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN" + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + } ] + } ] + } ] + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/MusicStreaming_searchSongs.json b/H11/src/graderPublic/resources/h11/MusicStreaming_searchSongs.json new file mode 100644 index 0000000..f16ae03 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/MusicStreaming_searchSongs.json @@ -0,0 +1,1240 @@ +[ { + "invoked" : 2, + "entryPoint" : "h11.MusicStreaming#searchSongs(java.util.function.Predicate)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 2, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 1, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 1 + } ], + "id" : 2 + }, { + "type" : "java.util.function.Predicate", + "fields" : [ ], + "id" : 0 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +}, { + "invoked" : 5, + "entryPoint" : "h11.MusicStreaming#searchSongs(java.util.function.Predicate)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 3, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 5, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 1 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 3 + } ], + "id" : 4 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 5 + }, { + "type" : "java.util.function.Predicate", + "fields" : [ ], + "id" : 0 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +}, { + "invoked" : 8, + "entryPoint" : "h11.MusicStreaming#searchSongs(java.util.function.Predicate)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 4, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 3, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 6, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 3, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 8, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 3, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "", + "id" : 1 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "COUNTRY", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 4 + } ], + "id" : 5 + } ], + "id" : 6 + } ], + "id" : 7 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 3 + } ], + "id" : 8 + }, { + "type" : "java.util.function.Predicate", + "fields" : [ ], + "id" : 0 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +}, { + "invoked" : 28, + "entryPoint" : "h11.MusicStreaming#searchSongs(java.util.function.Predicate)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 28, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 25, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 0, + "methodCalls" : [ { + "methodName" : "test", + "invocations" : [ { + "return" : 29, + "parameter" : [ 6 ] + }, { + "return" : 29, + "parameter" : [ 9 ] + }, { + "return" : 29, + "parameter" : [ 12 ] + }, { + "return" : 29, + "parameter" : [ 15 ] + }, { + "return" : 29, + "parameter" : [ 21 ] + }, { + "return" : 29, + "parameter" : [ 18 ] + } ] + } ] + }, { + "id" : 23, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4", + "id" : 1 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 2 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 3 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 4 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 8 + } ], + "id" : 9 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 10 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 16 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 17 + } ], + "id" : 18 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 19 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 20 + } ], + "id" : 21 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 4 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 8 + } ], + "id" : 9 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 10 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 16 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 17 + } ], + "id" : 18 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 19 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + } ], + "id" : 23 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 26 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 27 + } ], + "id" : 28 + }, { + "type" : "java.util.function.Predicate", + "fields" : [ ], + "id" : 0 + }, { + "type" : "java.lang.Boolean", + "value" : "false", + "id" : 29 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +}, { + "invoked" : 28, + "entryPoint" : "h11.MusicStreaming#searchSongs(java.util.function.Predicate)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 28, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 0, + "methodCalls" : [ { + "methodName" : "test", + "invocations" : [ { + "return" : 29, + "parameter" : [ 6 ] + }, { + "return" : 29, + "parameter" : [ 21 ] + }, { + "return" : 29, + "parameter" : [ 12 ] + }, { + "return" : 29, + "parameter" : [ 9 ] + }, { + "return" : 29, + "parameter" : [ 15 ] + }, { + "return" : 29, + "parameter" : [ 18 ] + } ] + } ] + }, { + "id" : 25, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 23, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 22, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4", + "id" : 1 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 2 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 3 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 4 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 8 + } ], + "id" : 9 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 10 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 16 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 17 + } ], + "id" : 18 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 19 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 20 + } ], + "id" : 21 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 4 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 8 + } ], + "id" : 9 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 10 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 11 + } ], + "id" : 12 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 13 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 14 + } ], + "id" : 15 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 16 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 17 + } ], + "id" : 18 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 19 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + } ], + "id" : 23 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 26 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 27 + } ], + "id" : 28 + }, { + "type" : "java.util.function.Predicate", + "fields" : [ ], + "id" : 0 + }, { + "type" : "java.lang.Boolean", + "value" : "true", + "id" : 29 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500" + } ] + } ] + } +}, { + "invoked" : 28, + "entryPoint" : "h11.MusicStreaming#searchSongs(java.util.function.Predicate)", + "arguments" : [ 0 ], + "calls" : [ { + "id" : 22, + "methodCalls" : [ { + "methodName" : "songs", + "invocations" : [ { + "return" : 21, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 28, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 21, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 0, + "methodCalls" : [ { + "methodName" : "test", + "invocations" : [ { + "return" : 29, + "parameter" : [ 5 ] + }, { + "return" : 29, + "parameter" : [ 11 ] + }, { + "return" : 30, + "parameter" : [ 20 ] + }, { + "return" : 30, + "parameter" : [ 8 ] + }, { + "return" : 29, + "parameter" : [ 17 ] + }, { + "return" : 30, + "parameter" : [ 14 ] + } ] + } ] + }, { + "id" : 25, + "methodCalls" : [ { + "methodName" : "getAllSongs", + "invocations" : [ { + "return" : 21, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.MusicStreaming", + "fields" : [ { + "name" : "artists", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Artist", + "fields" : [ { + "name" : "name", + "type" : "java.lang.String", + "value" : "Artist 4", + "id" : 23 + }, { + "name" : "albums", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Album", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Album 6", + "id" : 1 + }, { + "name" : "genre", + "type" : "h11.Genre", + "value" : "LATIN", + "id" : 2 + }, { + "name" : "songs", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 6 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 7 + } ], + "id" : 8 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 12 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 15 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 16 + } ], + "id" : 17 + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 18 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 19 + } ], + "id" : 20 + } ], + "id" : 21 + } ], + "id" : 22 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 26 + }, { + "name" : "users", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 27 + } ], + "id" : 28 + }, { + "type" : "java.util.function.Predicate", + "fields" : [ ], + "id" : 0 + }, { + "type" : "java.lang.Boolean", + "value" : "false", + "id" : 30 + }, { + "type" : "java.lang.Boolean", + "value" : "true", + "id" : 29 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0" + } ] + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/Song_isLongerThan.json b/H11/src/graderPublic/resources/h11/Song_isLongerThan.json new file mode 100644 index 0000000..fdcc9e1 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/Song_isLongerThan.json @@ -0,0 +1,161 @@ +[ { + "invoked" : 2, + "entryPoint" : "h11.Song#isLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 0 + } ], + "id" : 2 + } ], + "expected" : { + "type" : "java.lang.Boolean", + "value" : "false" + } +}, { + "invoked" : 3, + "entryPoint" : "h11.Song#isLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 2 + } ], + "id" : 3 + }, { + "type" : "java.lang.Integer", + "value" : "100", + "id" : 0 + } ], + "expected" : { + "type" : "java.lang.Boolean", + "value" : "true" + } +}, { + "invoked" : 3, + "entryPoint" : "h11.Song#isLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 2 + } ], + "id" : 3 + }, { + "type" : "java.lang.Integer", + "value" : "400", + "id" : 0 + } ], + "expected" : { + "type" : "java.lang.Boolean", + "value" : "false" + } +}, { + "invoked" : 2, + "entryPoint" : "h11.Song#isLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 4", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "400", + "id" : 0 + } ], + "id" : 2 + } ], + "expected" : { + "type" : "java.lang.Boolean", + "value" : "false" + } +}, { + "invoked" : 3, + "entryPoint" : "h11.Song#isLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 5", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "0", + "id" : 2 + } ], + "id" : 3 + }, { + "type" : "java.lang.Integer", + "value" : "400", + "id" : 0 + } ], + "expected" : { + "type" : "java.lang.Boolean", + "value" : "false" + } +}, { + "invoked" : 3, + "entryPoint" : "h11.Song#isLongerThan(int)", + "arguments" : [ 0 ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 6", + "id" : 1 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "500", + "id" : 2 + } ], + "id" : 3 + }, { + "type" : "java.lang.Integer", + "value" : "0", + "id" : 0 + } ], + "expected" : { + "type" : "java.lang.Boolean", + "value" : "true" + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/User_getPlayCounts_return.json b/H11/src/graderPublic/resources/h11/User_getPlayCounts_return.json new file mode 100644 index 0000000..55a9761 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/User_getPlayCounts_return.json @@ -0,0 +1,329 @@ +[ { + "invoked" : 22, + "entryPoint" : "h11.User#getPlayCounts()", + "arguments" : [ ], + "calls" : [ { + "id" : 2, + "methodCalls" : [ { + "methodName" : "title", + "invocations" : [ { + "return" : 0, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 9, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 5, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 14, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 12, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 12, + "methodCalls" : [ { + "methodName" : "title", + "invocations" : [ { + "return" : 10, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 16, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 5, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 20, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "User 3", + "id" : 17 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 18 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 6 + }, { + "name" : "cdate", + "type" : "null", + "id" : 7 + } ], + "id" : 15 + } ], + "id" : 16 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 10 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 11 + } ], + "id" : 12 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 6 + }, { + "name" : "cdate", + "type" : "null", + "id" : 7 + } ], + "id" : 13 + } ], + "id" : 14 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 1 + } ], + "id" : 2 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 6 + }, { + "name" : "cdate", + "type" : "null", + "id" : 7 + } ], + "id" : 19 + } ], + "id" : 20 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 6 + }, { + "name" : "cdate", + "type" : "null", + "id" : 7 + } ], + "id" : 8 + } ], + "id" : 9 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 3 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 4 + } ], + "id" : 5 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 6 + }, { + "name" : "cdate", + "type" : "null", + "id" : 7 + } ], + "id" : 8 + } ], + "id" : 9 + } ], + "id" : 21 + } ], + "id" : 22 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "java.lang.Long", + "value" : "3" + } ] + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "java.lang.Long", + "value" : "1" + } ] + }, { + "type" : "java.util.HashMap$Node", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + }, { + "type" : "java.lang.Long", + "value" : "1" + } ] + } ] + } +}, { + "invoked" : 3, + "entryPoint" : "h11.User#getPlayCounts()", + "arguments" : [ ], + "calls" : [ ], + "objects" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "User 6", + "id" : 0 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 1 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ ], + "id" : 2 + } ], + "id" : 3 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/User_getPlayedSongs_general.json b/H11/src/graderPublic/resources/h11/User_getPlayedSongs_general.json new file mode 100644 index 0000000..5569cb7 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/User_getPlayedSongs_general.json @@ -0,0 +1,189 @@ +[ { + "invoked" : 20, + "entryPoint" : "h11.User#getPlayedSongs()", + "arguments" : [ ], + "calls" : [ { + "id" : 6, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 11, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 9, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 18, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 16, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "User 1", + "id" : 12 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 13 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 7 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 8 + } ], + "id" : 9 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 10 + } ], + "id" : 11 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 1 + } ], + "id" : 2 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 15 + } ], + "id" : 16 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 17 + } ], + "id" : 18 + } ], + "id" : 19 + } ], + "id" : 20 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/h11/User_getPlayedSongs_unique.json b/H11/src/graderPublic/resources/h11/User_getPlayedSongs_unique.json new file mode 100644 index 0000000..d45e433 --- /dev/null +++ b/H11/src/graderPublic/resources/h11/User_getPlayedSongs_unique.json @@ -0,0 +1,315 @@ +[ { + "invoked" : 27, + "entryPoint" : "h11.User#getPlayedSongs()", + "arguments" : [ ], + "calls" : [ { + "id" : 6, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 21, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 11, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 23, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 2, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 13, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 11, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 25, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 16, + "parameter" : [ ] + } ] + } ] + }, { + "id" : 18, + "methodCalls" : [ { + "methodName" : "song", + "invocations" : [ { + "return" : 16, + "parameter" : [ ] + } ] + } ] + } ], + "objects" : [ { + "type" : "h11.User", + "fields" : [ { + "name" : "username", + "type" : "java.lang.String", + "value" : "User 2", + "id" : 7 + }, { + "name" : "pricePerMonth", + "type" : "java.lang.Double", + "value" : "0.0", + "id" : 8 + }, { + "name" : "playingHistory", + "type" : "java.util.ArrayList", + "value" : [ { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 10 + } ], + "id" : 11 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 12 + } ], + "id" : 13 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 1 + } ], + "id" : 2 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 5 + } ], + "id" : 6 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 15 + } ], + "id" : 16 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "0", + "id" : 3 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 17 + } ], + "id" : 18 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1", + "id" : 9 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100", + "id" : 10 + } ], + "id" : 11 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 19 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 20 + } ], + "id" : 21 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2", + "id" : 0 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200", + "id" : 1 + } ], + "id" : 2 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 19 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 22 + } ], + "id" : 23 + }, { + "type" : "h11.PlayedSong", + "fields" : [ { + "name" : "song", + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3", + "id" : 14 + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300", + "id" : 15 + } ], + "id" : 16 + }, { + "name" : "playedAt", + "type" : "java.util.Date", + "fields" : [ { + "name" : "fastTime", + "type" : "java.lang.Long", + "value" : "1", + "id" : 19 + }, { + "name" : "cdate", + "type" : "null", + "id" : 4 + } ], + "id" : 24 + } ], + "id" : 25 + } ], + "id" : 26 + } ], + "id" : 27 + } ], + "expected" : { + "type" : "java.util.ImmutableCollections$ListN", + "value" : [ { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 1" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "100" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 2" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "200" + } ] + }, { + "type" : "h11.Song", + "fields" : [ { + "name" : "title", + "type" : "java.lang.String", + "value" : "Song 3" + }, { + "name" : "durationInSeconds", + "type" : "java.lang.Integer", + "value" : "300" + } ] + } ] + } +} ] \ No newline at end of file diff --git a/H11/src/graderPublic/resources/packages.txt b/H11/src/graderPublic/resources/packages.txt new file mode 100644 index 0000000..bc6730e --- /dev/null +++ b/H11/src/graderPublic/resources/packages.txt @@ -0,0 +1 @@ +h11 \ No newline at end of file diff --git a/H11/src/main/java/h11/Album.java b/H11/src/main/java/h11/Album.java new file mode 100644 index 0000000..e4223d2 --- /dev/null +++ b/H11/src/main/java/h11/Album.java @@ -0,0 +1,39 @@ +package h11; + +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.List; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * Represents an album with a title, genre, and a list of songs. + * + * @param title the title of the album + * @param genre the genre of the album + * @param songs the list of songs on the album + */ +public record Album(String title, Genre genre, List songs) { + /** + * Returns a list of songs that are longer than the specified duration. + * + * @param durationInSeconds the duration in seconds to compare the song lengths against + * @return a list of songs that are longer than the specified duration + */ + @StudentImplementationRequired + public List getSongsLongerThan(int durationInSeconds) { + // TODO H11.1.1 + return crash(); + } + + /** + * Calculates the average duration of the songs on the album. + * + * @return the average duration of the songs in seconds. If there are no songs, returns 0. + */ + @StudentImplementationRequired + public double getAverageDuration() { + // TODO H11.1.2 + return crash(); + } +} diff --git a/H11/src/main/java/h11/Artist.java b/H11/src/main/java/h11/Artist.java new file mode 100644 index 0000000..6319afb --- /dev/null +++ b/H11/src/main/java/h11/Artist.java @@ -0,0 +1,37 @@ +package h11; + +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.List; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * Represents an artist with a name and a list of albums. + * + * @param name the name of the artist + * @param albums the list of albums released by the artist + */ +public record Artist(String name, List albums) { + /** + * Retrieves all the songs from the artist's albums. + * + * @return a list of all songs from the artist's albums + */ + @StudentImplementationRequired + public List getAllSongs() { + // TODO H11.2.1 + return crash(); + } + + /** + * Retrieves all unique genres from the artist's albums. + * + * @return a list of all unique genres from the artist's albums + */ + @StudentImplementationRequired + public List getAllGenres() { + // TODO H11.2.2 + return crash(); + } +} diff --git a/H11/src/main/java/h11/Genre.java b/H11/src/main/java/h11/Genre.java new file mode 100644 index 0000000..d164c80 --- /dev/null +++ b/H11/src/main/java/h11/Genre.java @@ -0,0 +1,24 @@ +package h11; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +/** + * An enum consisting of different music genres + */ +@DoNotTouch +public enum Genre { + ROCK, + POP, + JAZZ, + CLASSICAL, + HIPHOP, + RAP, + METAL, + COUNTRY, + ELECTRONIC, + DANCE, + LATIN, + ALTERNATIVE, + KPOP, + OTHER +} diff --git a/H11/src/main/java/h11/Main.java b/H11/src/main/java/h11/Main.java new file mode 100644 index 0000000..53be2c7 --- /dev/null +++ b/H11/src/main/java/h11/Main.java @@ -0,0 +1,15 @@ +package h11; + +/** + * Main entry point in executing the program. + */ +public class Main { + /** + * Main entry point in executing the program. + * + * @param args program arguments, currently ignored + */ + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/H11/src/main/java/h11/MusicStreaming.java b/H11/src/main/java/h11/MusicStreaming.java new file mode 100644 index 0000000..b17eaff --- /dev/null +++ b/H11/src/main/java/h11/MusicStreaming.java @@ -0,0 +1,171 @@ +package h11; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * Represents a music streaming service with a list of artists and a list of users. + * + * @param artists the list of artists + * @param users the list of users + */ +public record MusicStreaming(List artists, List users) { + /** + * Retrieves all the songs from all the artists on the platform. + * + * @return a list of all songs available on the platform + */ + @StudentImplementationRequired + public List getAllSongs() { + // TODO H11.4.1 + return crash(); + } + + /** + * Generates a stream of random songs from the platform. + * + * @return a stream of random songs + */ + @StudentImplementationRequired + public Stream generateRandomPlaylist() { + // TODO H11.4.2 + return crash(); + } + + /** + * Retrieves a random song from the platform's song list. + * + * @return a random song, or null if there are no songs available + */ + @DoNotTouch + public Song getRandomSong() { + List allSongs = getAllSongs(); + if (allSongs.isEmpty()) { + return null; + } + return allSongs.get((int) (Math.random() * allSongs.size())); + } + + /** + * Retrieves a list of songs that are longer than the specified duration. + * + * @param durationInSeconds the duration in seconds to compare the song lengths against + * @return a list of songs that are longer than the specified duration + */ + @StudentImplementationRequired + public List getSongsLongerThan(int durationInSeconds) { + // TODO H11.4.3 + return crash(); + } + + /** + * Retrieves all unique genres available on the platform. + * + * @return a list of all unique genres available on the platform + */ + @StudentImplementationRequired + public List getAllGenres() { + // TODO H11.4.4 + return crash(); + } + + /** + * Groups all albums by their genre. + * + * @return a map where the key is the genre and the value is a list of albums of that genre + */ + @StudentImplementationRequired + public Map> getAlbumsByGenre() { + // TODO H11.4.5 + return crash(); + } + + /** + * Calculates the global play counts for all songs by summing the play counts from all users. + * + * @return a list of entries where each entry is a song and its total play count, sorted by play count in descending order. + * Songs with the same play count are ordered alphabetically by the song title. + */ + @StudentImplementationRequired + public List> getGlobalPlayCounts() { + // TODO H11.4.6 + return crash(); + } + + /** + * Retrieves a list of the top played songs formatted as strings. + * + * @return a list of strings representing the top 5 most played songs and their play counts in the format "[title] ([count] plays)" + */ + @StudentImplementationRequired + public List getTopPlayedSongsList() { + // TODO H11.4.6 + return crash(); + } + + /** + * Retrieves the total playtime of an artist's songs based on global play counts. + * + * @param artist the artist whose playtime is to be calculated + * @return the total playtime of the artist's songs in seconds + */ + @StudentImplementationRequired + public long getArtistPlaytime(Artist artist) { + // TODO H11.4.7 + return crash(); + } + + /** + * Retrieves the total playtimes for all artists. + * + * @return a map where the key is the artist and the value is their total playtime in seconds + */ + @StudentImplementationRequired + public Map getArtistPlaytimes() { + // TODO H11.4.7 + return crash(); + } + + /** + * Retrieves the most played artist based on the total playtime of their songs. + * + * @return the most played artist, or null if there are no artists + */ + @StudentImplementationRequired + public Artist getMostPlayedArtist() { + // TODO H11.4.8 + return crash(); + } + + /** + * Searches for songs that match the given predicate. + * + * @param predicate the predicate to filter songs + * @return a list of songs that match the predicate + */ + @StudentImplementationRequired + public List searchSongs(Predicate predicate) { + // TODO H11.4.9 + return crash(); + } + + /** + * Adjusts the monthly subscription price for all users by a given percentage. + * + * @param percentage the percentage to adjust the price by (e.g., 0.10 for a 10% increase) + */ + @StudentImplementationRequired + public void adjustPrice(double percentage) { + // TODO H11.4.10 + crash(); + } +} diff --git a/H11/src/main/java/h11/PlayedSong.java b/H11/src/main/java/h11/PlayedSong.java new file mode 100644 index 0000000..d1edfeb --- /dev/null +++ b/H11/src/main/java/h11/PlayedSong.java @@ -0,0 +1,12 @@ +package h11; + +import java.util.Date; + +/** + * Represents a song that was played at a specific time. + * + * @param song the song that was played + * @param playedAt the date and time when the song was played + */ +public record PlayedSong(Song song, Date playedAt) { +} diff --git a/H11/src/main/java/h11/Song.java b/H11/src/main/java/h11/Song.java new file mode 100644 index 0000000..90597ed --- /dev/null +++ b/H11/src/main/java/h11/Song.java @@ -0,0 +1,25 @@ +package h11; + +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * Represents a song with a title and duration. + * + * @param title the title of the song + * @param durationInSeconds the duration of the song in seconds + */ +public record Song(String title, int durationInSeconds) { + /** + * Checks if the song is longer than the specified duration. + * + * @param durationInSeconds the duration in seconds to compare against + * @return true if the song's duration is greater than the specified duration, false otherwise + */ + @StudentImplementationRequired + public boolean isLongerThan(int durationInSeconds) { + // TODO H11.1.1 + return crash(); + } +} diff --git a/H11/src/main/java/h11/User.java b/H11/src/main/java/h11/User.java new file mode 100644 index 0000000..4ceab15 --- /dev/null +++ b/H11/src/main/java/h11/User.java @@ -0,0 +1,142 @@ +package h11; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.tudalgo.algoutils.student.Student.crash; + +/** + * Represents a user of the music streaming platform. + */ +public class User { + private final String username; + private double pricePerMonth; + private List playingHistory; + + /** + * Constructs a new User with the specified username, monthly price, and playing history. + * + * @param username the username of the user + * @param pricePerMonth the monthly subscription price for the user + * @param playingHistory the list of songs played by the user + */ + @DoNotTouch + public User(String username, double pricePerMonth, List playingHistory) { + this.username = username; + this.pricePerMonth = pricePerMonth; + this.playingHistory = playingHistory; + } + + @Override + @DoNotTouch + public String toString() { + return "User{" + + "username='" + username + '\'' + + ", pricePerMonth=" + pricePerMonth + + ", playingHistory=" + playingHistory + + '}'; + } + + @Override + @DoNotTouch + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof User user)) return false; + return Double.compare(pricePerMonth, user.pricePerMonth) == 0 && Objects.equals(username, user.username) && Objects.equals(playingHistory, user.playingHistory); + } + + @Override + @DoNotTouch + public int hashCode() { + return Objects.hash(username, pricePerMonth, playingHistory); + } + + /** + * Retrieves the username of the user. + * + * @return the username of the user + */ + @DoNotTouch + public String getUsername() { + return username; + } + /** + * Retrieves the monthly subscription price for the user. + * + * @return the monthly subscription price for the user + */ + @DoNotTouch + public double getPricePerMonth() { + return pricePerMonth; + } + /** + * Retrieves the list of songs played by the user. + * + * @return the playing history of the user + */ + @DoNotTouch + public List getPlayingHistory() { + return playingHistory; + } + + /** + * Sets the monthly subscription price for the user. + * + * @param pricePerMonth the new monthly subscription price for the user + */ + @DoNotTouch + public void setPricePerMonth(double pricePerMonth) { + this.pricePerMonth = pricePerMonth; + } + + /** + * Retrieves the list of unique songs played by the user. + * + * @return a list of unique songs played by the user + */ + @StudentImplementationRequired + public List getPlayedSongs() { + // TODO H11.3.1 + return crash(); + } + + /** + * Retrieves the play counts for each song played by the user. + * + * @return a list of entries where each entry is a song and its play count, sorted by play count in descending order. + * Songs with the same play count are ordered alphabetically by the song title. + */ + @StudentImplementationRequired + public List> getPlayCounts() { + // TODO H11.3.2 + return crash(); + } + + /** + * Retrieves the user's favorite song based on play count. + * + * @return the user's favorite song, or null if there are no played songs + */ + @StudentImplementationRequired + public Song getFavoriteSong() { + // TODO H11.3.3 + return crash(); + } + + /** + * Retrieves a list of the top played songs of the user formatted as strings. + * + * @return a list of strings representing the top 3 most played songs of the user and their play counts in the format "[title] ([count] plays)" + */ + @StudentImplementationRequired + public List getTopPlayedSongsList() { + // TODO H11.3.4 + return crash(); + } +} diff --git a/H11/src/test/java/h11/ExampleJUnitTest.java b/H11/src/test/java/h11/ExampleJUnitTest.java new file mode 100644 index 0000000..683ff98 --- /dev/null +++ b/H11/src/test/java/h11/ExampleJUnitTest.java @@ -0,0 +1,16 @@ +package h11; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * An example JUnit test class. + */ +public class ExampleJUnitTest { + + @Test + public void testAddition() { + assertEquals(2, 1 + 1); + } +} diff --git a/H12/.editorconfig b/H12/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/H12/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/H12/.gitignore b/H12/.gitignore new file mode 100644 index 0000000..367960a --- /dev/null +++ b/H12/.gitignore @@ -0,0 +1,85 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof diff --git a/H12/README.md b/H12/README.md new file mode 100644 index 0000000..79931c5 --- /dev/null +++ b/H12/README.md @@ -0,0 +1,4 @@ +# Vorlage zu Hausübung 12 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/H12/build.gradle.kts b/H12/build.gradle.kts new file mode 100644 index 0000000..3497621 --- /dev/null +++ b/H12/build.gradle.kts @@ -0,0 +1,31 @@ +plugins { + alias(libs.plugins.algomate) +} + +exercise { + assignmentId.set("h12") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "" + firstName = "" + lastName = "" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h12.H12_RubricProviderPublic") + } + } +} diff --git a/H12/gradle/libs.versions.toml b/H12/gradle/libs.versions.toml new file mode 100644 index 0000000..46d58d4 --- /dev/null +++ b/H12/gradle/libs.versions.toml @@ -0,0 +1,2 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } diff --git a/H12/gradle/wrapper/gradle-wrapper.jar b/H12/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 zcma&N1CXTcmMvW9vTb(Rwr$&4wr$(C?dmSu>@vG-+vuvg^_??!{yS%8zW-#zn-LkA z5&1^$^{lnmUON?}LBF8_K|(?T0Ra(xUH{($5eN!MR#ZihR#HxkUPe+_R8Cn`RRs(P z_^*#_XlXmGv7!4;*Y%p4nw?{bNp@UZHv1?Um8r6)Fei3p@ClJn0ECfg1hkeuUU@Or zDaPa;U3fE=3L}DooL;8f;P0ipPt0Z~9P0)lbStMS)ag54=uL9ia-Lm3nh|@(Y?B`; zx_#arJIpXH!U{fbCbI^17}6Ri*H<>OLR%c|^mh8+)*h~K8Z!9)DPf zR2h?lbDZQ`p9P;&DQ4F0sur@TMa!Y}S8irn(%d-gi0*WxxCSk*A?3lGh=gcYN?FGl z7D=Js!i~0=u3rox^eO3i@$0=n{K1lPNU zwmfjRVmLOCRfe=seV&P*1Iq=^i`502keY8Uy-WNPwVNNtJFx?IwAyRPZo2Wo1+S(xF37LJZ~%i)kpFQ3Fw=mXfd@>%+)RpYQLnr}B~~zoof(JVm^^&f zxKV^+3D3$A1G;qh4gPVjhrC8e(VYUHv#dy^)(RoUFM?o%W-EHxufuWf(l*@-l+7vt z=l`qmR56K~F|v<^Pd*p~1_y^P0P^aPC##d8+HqX4IR1gu+7w#~TBFphJxF)T$2WEa zxa?H&6=Qe7d(#tha?_1uQys2KtHQ{)Qco)qwGjrdNL7thd^G5i8Os)CHqc>iOidS} z%nFEDdm=GXBw=yXe1W-ShHHFb?Cc70+$W~z_+}nAoHFYI1MV1wZegw*0y^tC*s%3h zhD3tN8b=Gv&rj}!SUM6|ajSPp*58KR7MPpI{oAJCtY~JECm)*m_x>AZEu>DFgUcby z1Qaw8lU4jZpQ_$;*7RME+gq1KySGG#Wql>aL~k9tLrSO()LWn*q&YxHEuzmwd1?aAtI zBJ>P=&$=l1efe1CDU;`Fd+_;&wI07?V0aAIgc(!{a z0Jg6Y=inXc3^n!U0Atk`iCFIQooHqcWhO(qrieUOW8X(x?(RD}iYDLMjSwffH2~tB z)oDgNBLB^AJBM1M^c5HdRx6fBfka`(LD-qrlh5jqH~);#nw|iyp)()xVYak3;Ybik z0j`(+69aK*B>)e_p%=wu8XC&9e{AO4c~O1U`5X9}?0mrd*m$_EUek{R?DNSh(=br# z#Q61gBzEpmy`$pA*6!87 zSDD+=@fTY7<4A?GLqpA?Pb2z$pbCc4B4zL{BeZ?F-8`s$?>*lXXtn*NC61>|*w7J* z$?!iB{6R-0=KFmyp1nnEmLsA-H0a6l+1uaH^g%c(p{iT&YFrbQ$&PRb8Up#X3@Zsk zD^^&LK~111%cqlP%!_gFNa^dTYT?rhkGl}5=fL{a`UViaXWI$k-UcHJwmaH1s=S$4 z%4)PdWJX;hh5UoK?6aWoyLxX&NhNRqKam7tcOkLh{%j3K^4Mgx1@i|Pi&}<^5>hs5 zm8?uOS>%)NzT(%PjVPGa?X%`N2TQCKbeH2l;cTnHiHppPSJ<7y-yEIiC!P*ikl&!B z%+?>VttCOQM@ShFguHVjxX^?mHX^hSaO_;pnyh^v9EumqSZTi+#f&_Vaija0Q-e*| z7ulQj6Fs*bbmsWp{`auM04gGwsYYdNNZcg|ph0OgD>7O}Asn7^Z=eI>`$2*v78;sj-}oMoEj&@)9+ycEOo92xSyY344^ z11Hb8^kdOvbf^GNAK++bYioknrpdN>+u8R?JxG=!2Kd9r=YWCOJYXYuM0cOq^FhEd zBg2puKy__7VT3-r*dG4c62Wgxi52EMCQ`bKgf*#*ou(D4-ZN$+mg&7$u!! z-^+Z%;-3IDwqZ|K=ah85OLwkO zKxNBh+4QHh)u9D?MFtpbl)us}9+V!D%w9jfAMYEb>%$A;u)rrI zuBudh;5PN}_6J_}l55P3l_)&RMlH{m!)ai-i$g)&*M`eN$XQMw{v^r@-125^RRCF0 z^2>|DxhQw(mtNEI2Kj(;KblC7x=JlK$@78`O~>V!`|1Lm-^JR$-5pUANAnb(5}B}JGjBsliK4& zk6y(;$e&h)lh2)L=bvZKbvh@>vLlreBdH8No2>$#%_Wp1U0N7Ank!6$dFSi#xzh|( zRi{Uw%-4W!{IXZ)fWx@XX6;&(m_F%c6~X8hx=BN1&q}*( zoaNjWabE{oUPb!Bt$eyd#$5j9rItB-h*5JiNi(v^e|XKAj*8(k<5-2$&ZBR5fF|JA z9&m4fbzNQnAU}r8ab>fFV%J0z5awe#UZ|bz?Ur)U9bCIKWEzi2%A+5CLqh?}K4JHi z4vtM;+uPsVz{Lfr;78W78gC;z*yTch~4YkLr&m-7%-xc ztw6Mh2d>_iO*$Rd8(-Cr1_V8EO1f*^@wRoSozS) zy1UoC@pruAaC8Z_7~_w4Q6n*&B0AjOmMWa;sIav&gu z|J5&|{=a@vR!~k-OjKEgPFCzcJ>#A1uL&7xTDn;{XBdeM}V=l3B8fE1--DHjSaxoSjNKEM9|U9#m2<3>n{Iuo`r3UZp;>GkT2YBNAh|b z^jTq-hJp(ebZh#Lk8hVBP%qXwv-@vbvoREX$TqRGTgEi$%_F9tZES@z8Bx}$#5eeG zk^UsLBH{bc2VBW)*EdS({yw=?qmevwi?BL6*=12k9zM5gJv1>y#ML4!)iiPzVaH9% zgSImetD@dam~e>{LvVh!phhzpW+iFvWpGT#CVE5TQ40n%F|p(sP5mXxna+Ev7PDwA zamaV4m*^~*xV+&p;W749xhb_X=$|LD;FHuB&JL5?*Y2-oIT(wYY2;73<^#46S~Gx| z^cez%V7x$81}UWqS13Gz80379Rj;6~WdiXWOSsdmzY39L;Hg3MH43o*y8ibNBBH`(av4|u;YPq%{R;IuYow<+GEsf@R?=@tT@!}?#>zIIn0CoyV!hq3mw zHj>OOjfJM3F{RG#6ujzo?y32m^tgSXf@v=J$ELdJ+=5j|=F-~hP$G&}tDZsZE?5rX ztGj`!S>)CFmdkccxM9eGIcGnS2AfK#gXwj%esuIBNJQP1WV~b~+D7PJTmWGTSDrR` zEAu4B8l>NPuhsk5a`rReSya2nfV1EK01+G!x8aBdTs3Io$u5!6n6KX%uv@DxAp3F@{4UYg4SWJtQ-W~0MDb|j-$lwVn znAm*Pl!?Ps&3wO=R115RWKb*JKoexo*)uhhHBncEDMSVa_PyA>k{Zm2(wMQ(5NM3# z)jkza|GoWEQo4^s*wE(gHz?Xsg4`}HUAcs42cM1-qq_=+=!Gk^y710j=66(cSWqUe zklbm8+zB_syQv5A2rj!Vbw8;|$@C!vfNmNV!yJIWDQ>{+2x zKjuFX`~~HKG~^6h5FntRpnnHt=D&rq0>IJ9#F0eM)Y-)GpRjiN7gkA8wvnG#K=q{q z9dBn8_~wm4J<3J_vl|9H{7q6u2A!cW{bp#r*-f{gOV^e=8S{nc1DxMHFwuM$;aVI^ zz6A*}m8N-&x8;aunp1w7_vtB*pa+OYBw=TMc6QK=mbA-|Cf* zvyh8D4LRJImooUaSb7t*fVfih<97Gf@VE0|z>NcBwBQze);Rh!k3K_sfunToZY;f2 z^HmC4KjHRVg+eKYj;PRN^|E0>Gj_zagfRbrki68I^#~6-HaHg3BUW%+clM1xQEdPYt_g<2K+z!$>*$9nQ>; zf9Bei{?zY^-e{q_*|W#2rJG`2fy@{%6u0i_VEWTq$*(ZN37|8lFFFt)nCG({r!q#9 z5VK_kkSJ3?zOH)OezMT{!YkCuSSn!K#-Rhl$uUM(bq*jY? zi1xbMVthJ`E>d>(f3)~fozjg^@eheMF6<)I`oeJYx4*+M&%c9VArn(OM-wp%M<-`x z7sLP1&3^%Nld9Dhm@$3f2}87!quhI@nwd@3~fZl_3LYW-B?Ia>ui`ELg z&Qfe!7m6ze=mZ`Ia9$z|ARSw|IdMpooY4YiPN8K z4B(ts3p%2i(Td=tgEHX z0UQ_>URBtG+-?0E;E7Ld^dyZ;jjw0}XZ(}-QzC6+NN=40oDb2^v!L1g9xRvE#@IBR zO!b-2N7wVfLV;mhEaXQ9XAU+>=XVA6f&T4Z-@AX!leJ8obP^P^wP0aICND?~w&NykJ#54x3_@r7IDMdRNy4Hh;h*!u(Ol(#0bJdwEo$5437-UBjQ+j=Ic>Q2z` zJNDf0yO6@mr6y1#n3)s(W|$iE_i8r@Gd@!DWDqZ7J&~gAm1#~maIGJ1sls^gxL9LLG_NhU!pTGty!TbhzQnu)I*S^54U6Yu%ZeCg`R>Q zhBv$n5j0v%O_j{QYWG!R9W?5_b&67KB$t}&e2LdMvd(PxN6Ir!H4>PNlerpBL>Zvyy!yw z-SOo8caEpDt(}|gKPBd$qND5#a5nju^O>V&;f890?yEOfkSG^HQVmEbM3Ugzu+UtH zC(INPDdraBN?P%kE;*Ae%Wto&sgw(crfZ#Qy(<4nk;S|hD3j{IQRI6Yq|f^basLY; z-HB&Je%Gg}Jt@={_C{L$!RM;$$|iD6vu#3w?v?*;&()uB|I-XqEKqZPS!reW9JkLewLb!70T7n`i!gNtb1%vN- zySZj{8-1>6E%H&=V}LM#xmt`J3XQoaD|@XygXjdZ1+P77-=;=eYpoEQ01B@L*a(uW zrZeZz?HJsw_4g0vhUgkg@VF8<-X$B8pOqCuWAl28uB|@r`19DTUQQsb^pfqB6QtiT z*`_UZ`fT}vtUY#%sq2{rchyfu*pCg;uec2$-$N_xgjZcoumE5vSI{+s@iLWoz^Mf; zuI8kDP{!XY6OP~q5}%1&L}CtfH^N<3o4L@J@zg1-mt{9L`s^z$Vgb|mr{@WiwAqKg zp#t-lhrU>F8o0s1q_9y`gQNf~Vb!F%70f}$>i7o4ho$`uciNf=xgJ>&!gSt0g;M>*x4-`U)ysFW&Vs^Vk6m%?iuWU+o&m(2Jm26Y(3%TL; zA7T)BP{WS!&xmxNw%J=$MPfn(9*^*TV;$JwRy8Zl*yUZi8jWYF>==j~&S|Xinsb%c z2?B+kpet*muEW7@AzjBA^wAJBY8i|#C{WtO_or&Nj2{=6JTTX05}|H>N2B|Wf!*3_ z7hW*j6p3TvpghEc6-wufFiY!%-GvOx*bZrhZu+7?iSrZL5q9}igiF^*R3%DE4aCHZ zqu>xS8LkW+Auv%z-<1Xs92u23R$nk@Pk}MU5!gT|c7vGlEA%G^2th&Q*zfg%-D^=f z&J_}jskj|Q;73NP4<4k*Y%pXPU2Thoqr+5uH1yEYM|VtBPW6lXaetokD0u z9qVek6Q&wk)tFbQ8(^HGf3Wp16gKmr>G;#G(HRBx?F`9AIRboK+;OfHaLJ(P>IP0w zyTbTkx_THEOs%Q&aPrxbZrJlio+hCC_HK<4%f3ZoSAyG7Dn`=X=&h@m*|UYO-4Hq0 z-Bq&+Ie!S##4A6OGoC~>ZW`Y5J)*ouaFl_e9GA*VSL!O_@xGiBw!AF}1{tB)z(w%c zS1Hmrb9OC8>0a_$BzeiN?rkPLc9%&;1CZW*4}CDDNr2gcl_3z+WC15&H1Zc2{o~i) z)LLW=WQ{?ricmC`G1GfJ0Yp4Dy~Ba;j6ZV4r{8xRs`13{dD!xXmr^Aga|C=iSmor% z8hi|pTXH)5Yf&v~exp3o+sY4B^^b*eYkkCYl*T{*=-0HniSA_1F53eCb{x~1k3*`W zr~};p1A`k{1DV9=UPnLDgz{aJH=-LQo<5%+Em!DNN252xwIf*wF_zS^!(XSm(9eoj z=*dXG&n0>)_)N5oc6v!>-bd(2ragD8O=M|wGW z!xJQS<)u70m&6OmrF0WSsr@I%T*c#Qo#Ha4d3COcX+9}hM5!7JIGF>7<~C(Ear^Sn zm^ZFkV6~Ula6+8S?oOROOA6$C&q&dp`>oR-2Ym3(HT@O7Sd5c~+kjrmM)YmgPH*tL zX+znN>`tv;5eOfX?h{AuX^LK~V#gPCu=)Tigtq9&?7Xh$qN|%A$?V*v=&-2F$zTUv z`C#WyIrChS5|Kgm_GeudCFf;)!WH7FI60j^0o#65o6`w*S7R@)88n$1nrgU(oU0M9 zx+EuMkC>(4j1;m6NoGqEkpJYJ?vc|B zOlwT3t&UgL!pX_P*6g36`ZXQ; z9~Cv}ANFnJGp(;ZhS(@FT;3e)0)Kp;h^x;$*xZn*k0U6-&FwI=uOGaODdrsp-!K$Ac32^c{+FhI-HkYd5v=`PGsg%6I`4d9Jy)uW0y%) zm&j^9WBAp*P8#kGJUhB!L?a%h$hJgQrx!6KCB_TRo%9{t0J7KW8!o1B!NC)VGLM5! zpZy5Jc{`r{1e(jd%jsG7k%I+m#CGS*BPA65ZVW~fLYw0dA-H_}O zrkGFL&P1PG9p2(%QiEWm6x;U-U&I#;Em$nx-_I^wtgw3xUPVVu zqSuKnx&dIT-XT+T10p;yjo1Y)z(x1fb8Dzfn8e yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/H12/gradlew.bat b/H12/gradlew.bat new file mode 100644 index 0000000..25da30d --- /dev/null +++ b/H12/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/H12/settings.gradle.kts b/H12/settings.gradle.kts new file mode 100644 index 0000000..a6127c5 --- /dev/null +++ b/H12/settings.gradle.kts @@ -0,0 +1,10 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + } +} + +rootProject.name = "H12-Student" diff --git a/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java b/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java new file mode 100644 index 0000000..8b42d02 --- /dev/null +++ b/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java @@ -0,0 +1,305 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.Links; +import h12.assertions.TestConstants; +import h12.io.BufferedBitInputStream; +import h12.lang.MyByte; +import h12.mock.MockBitInputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +/** + * Defines the public tests for H12.1.1. + * + * @author Nhan Huynh + */ + +@TestForSubmission +@DisplayName("H12.1.1 | Bits lesen") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_1_1_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "bitsPreState", JsonConverters::toBitInputStream, + "bufferPreState", JsonConverters::toMyByte, + "positionPreState", JsonNode::asInt, + "bitsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "bufferPostState", JsonConverters::toMyByte, + "positionPostState", JsonNode::asInt, + "expectedBit", JsonNode::asInt + ); + + @Override + public Class getTestClass() { + return BufferedBitInputStream.class; + } + + /** + * The field link for the buffer field. + */ + private FieldLink buffer; + + /** + * The field link for the position field. + */ + private FieldLink position; + + /** + * The underlying byte array input stream for the input stream to test. + */ + private @Nullable MockBitInputStream underlying; + + /** + * The input stream to test. + */ + private @Nullable BufferedBitInputStream stream; + + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + buffer = Links.getField(getType(), "buffer"); + position = Links.getField(getType(), "position"); + } + + @AfterEach + void tearDown() throws IOException { + if (underlying != null) { + underlying.close(); + } + if (stream != null) { + stream.close(); + } + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest(MethodLink method, JsonParameterSet parameters) { + // Test setup + underlying = Objects.requireNonNull(parameters.get("bitsPreState")); + stream = new BufferedBitInputStream(underlying); + + MyByte bufferPreState = parameters.get("bufferPreState"); + buffer.set(stream, bufferPreState); + int positionPreState = parameters.get("positionPreState"); + position.set(stream, positionPreState); + + List bitsPostState = parameters.get("bitsPostState"); + MyByte bufferPostState = parameters.get("bufferPostState"); + int positionPostState = parameters.get("positionPostState"); + + return testInformation(method) + .preState( + TestInformation.builder() + .add("underlying", underlying.getBits()) + .add("buffer", bufferPreState) + .add("position", positionPreState) + .build() + ) + .postState( + TestInformation.builder() + .add("underlying", bitsPostState) + .add("buffer", bufferPostState) + .add("position", positionPostState) + .build() + ); + } + + /** + * Asserts the fetch() method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + void assertFetch(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("fetch"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + method.invoke(stream); + + // Test evaluation + MyByte bufferPostState = parameters.get("bufferPostState"); + int positionPostState = parameters.get("positionPostState"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + Context context = builder.actualState( + TestInformation.builder() + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(bufferPostState, bufferActualState, context, comment -> "Buffer is not updated correctly."); + Assertions2.assertEquals(positionPostState, positionActualState, context, + comment -> "Position is not updated correctly."); + } + + @DisplayName("Die Methode fetch() aktualisiert im Falle von nicht EOF den Puffer und die Position korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testFetchNotEOF.json", customConverters = CUSTOM_CONVERTERS) + void testFetchNotEOF(JsonParameterSet parameters) throws Throwable { + assertFetch(parameters); + } + + @DisplayName("Die Methode fetch() aktualisiert im Falle von EOF den Puffer und die Position korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testFetchEOF.json", customConverters = CUSTOM_CONVERTERS) + void testFetchEOF(JsonParameterSet parameters) throws Throwable { + assertFetch(parameters); + } + + /** + * Asserts the readBit() method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurso + */ + private void assertReadBit(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("readBit"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + int actualBit = method.invoke(stream); + + // Test evaluation + int expectedBit = parameters.get("expectedBit"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + Context context = builder.actualState( + TestInformation.builder() + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(expectedBit, actualBit, context, + comment -> "Return value is not correct."); + } + + @DisplayName("Die Methode readBit() liest das nächste Bit korrekt, falls wir bereits alle Bits des vorherigen Bytes gelesen haben.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitNextByte.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitNextByte(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von Lesen des ersten Bit das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitBufferStart.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitByteStart(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von Lesen eines mittleren Bit das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitBufferMiddle.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitByteMiddle(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von Lesen des letzen Bit eines Bytes das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitBufferEnd.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitByteEnd(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von EOF das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitEOF.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitEOF(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + /** + * Asserts that the method read() returns the correct result. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + private void assertRead(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("read"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + int actualByte = method.invoke(stream); + + // Test evaluation + int expectedByte = parameters.get("expectedByte"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + Context context = builder.actualState( + TestInformation.builder() + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(expectedByte, actualByte, context, comment -> "Return value is not correct."); + } + + @DisplayName("Die Methode read() gibt das korrekte Ergebnis zurück, falls wir am Ende des Streams sind.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadEnd.json", customConverters = CUSTOM_CONVERTERS) + void testReadEnd(JsonParameterSet parameters) throws Throwable { + assertRead(parameters); + } + + @DisplayName("Die Methode read() gibt das korrekte Teilergebnis zurück, falls der Stream keine 8 Bits mehr enthält.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadPartial.json", customConverters = CUSTOM_CONVERTERS) + void testReadPartial(JsonParameterSet parameters) throws Throwable { + assertRead(parameters); + } + + @DisplayName("Die Methode read() gibt in allen anderen Fallen das korrekte Ergebnis zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testRead.json", customConverters = CUSTOM_CONVERTERS) + void testRead(JsonParameterSet parameters) throws Throwable { + assertRead(parameters); + } +} diff --git a/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java b/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java new file mode 100644 index 0000000..e06f846 --- /dev/null +++ b/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java @@ -0,0 +1,233 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.Links; +import h12.assertions.TestConstants; +import h12.io.compress.rle.BitRunningLengthCompressor; +import h12.mock.MockBitInputStream; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H12.1.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.2.1 | BitRunningLengthCompressor") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_2_1_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "bit", JsonNode::asInt, + "count", JsonNode::asInt, + "bitsPreState", JsonConverters::toBitInputStream, + "lastReadPreState", JsonNode::asInt, + "bitsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "lastReadPostState", JsonNode::asInt, + "startBits", node -> JsonConverters.toList(node, JsonNode::asInt), + "counts", node -> JsonConverters.toList(node, JsonNode::asInt), + "compressedBits", node -> JsonConverters.toList(node, JsonNode::asInt) + ); + + /** + * The compressor to test. + */ + private @Nullable BitRunningLengthCompressor compressor; + + /** + * The field link for the lastRead field. + */ + private FieldLink lastRead; + + @Override + public Class getTestClass() { + return BitRunningLengthCompressor.class; + } + + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + lastRead = Links.getField(getType(), "lastRead"); + } + + @AfterEach + void tearDown() throws Exception { + if (compressor != null) { + compressor.close(); + } + } + + /** + * Asserts the getBitCount() method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + private void assertGetBitCount(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("getBitCount", int.class); + + // Test setup + MockBitInputStream in = parameters.get("bitsPreState"); + int lastReadPreState = parameters.getInt("lastReadPreState"); + MockBitOutputStream out = new MockBitOutputStream(); + compressor = new BitRunningLengthCompressor(in, out); + lastRead.set(compressor, lastReadPreState); + List bitsPostState = parameters.get("bitsPostState"); + int lastReadPostState = parameters.getInt("lastReadPostState"); + int bit = parameters.getInt("bit"); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", in.getBits()) + .add("out", List.of()) + .add("lastRead", lastReadPreState) + .add("bit", bit) + .build() + ) + .postState( + TestInformation.builder() + .add("in", bitsPostState) + .add("out", List.of()) + .add("lastRead", lastReadPostState) + .build() + ); + + // Test execution + int actualCount = method.invoke(compressor, bit); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + int expectedCount = parameters.getInt("count"); + int lastReadActual = lastRead.get(compressor); + + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getRemainingBits()) + .add("out", List.of()) + .add("lastRead", lastReadActual) + .build() + ).build(); + + Assertions2.assertEquals(lastReadPostState, lastReadActual, context, + comment -> "Last read bit is not updated correctly."); + Assertions2.assertEquals(expectedCount, actualCount, context, + comment -> "Computation of the count is incorrect."); + } + + @DisplayName("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits nichtmaximal ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_Tests_testGetBitCountNotMax.json", customConverters = CUSTOM_CONVERTERS) + void testGetBitCountNotMax(JsonParameterSet parameters) throws Throwable { + assertGetBitCount(parameters); + } + + @DisplayName("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits maximal ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_Tests_testGetBitCountMax.json", customConverters = CUSTOM_CONVERTERS) + void testGetBitCountMax(JsonParameterSet parameters) throws Throwable { + assertGetBitCount(parameters); + } + + @DisplayName("Die Methode compress() komprimiert korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_Tests_testCompress.json", customConverters = CUSTOM_CONVERTERS) + void testCompress(JsonParameterSet parameters) throws IOException { + // Access method to test + MethodLink method = Links.getMethod(getType(), "compress"); + + // Test setup + MockBitInputStream in = parameters.get("bitsPreState"); + int lastReadPreState = parameters.getInt("lastReadPreState"); + List bitsPostState = parameters.get("bitsPostState"); + int lastReadPostState = parameters.getInt("lastReadPostState"); + MockBitOutputStream out = new MockBitOutputStream(); + List compressedBits = parameters.get("compressedBits"); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", in.getBits()) + .add("out", out.getBits()) + .add("lastRead", lastReadPreState) + .build() + ) + .postState( + TestInformation.builder() + .add("in", bitsPostState) + .add("out", compressedBits) + .add("lastRead", lastReadPostState) + .build() + ); + + // Test execution + List startBits = parameters.get("startBits"); + List counts = parameters.get("counts"); + + // Custom gitBitCount to make the evaluation of compress() independent of getBitCount() + compressor = new BitRunningLengthCompressor(in, out) { + private int i = 0; + + @Override + protected int getBitCount(int bit) throws IOException { + int startBit = startBits.get(i); + int count = counts.get(i); + Assertions2.assertEquals(startBit, bit, builder.build(), + comment -> "Unexpected call of getBitCount(%s)".formatted(bit)); + if (i + 1 < counts.size()) { + lastRead.set(this, startBits.get(i + 1)); + } else { + lastRead.set(this, -1); + } + i++; + return count; + } + }; + compressor.compress(); + + // Test evaluation + int lastReadActual = lastRead.get(compressor); + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getRemainingBits()) + .add("out", out.getBits()) + .add("lastRead", lastReadActual) + .build() + ).build(); + + Assertions2.assertTrue(out.isFlushed(), context, + comment -> "The output stream is not flushed."); + Assertions2.assertEquals(compressedBits, out.getBits(), context, + comment -> "The compressed bits are incorrect."); + Assertions2.assertEquals(lastReadPostState, lastReadActual, context, + comment -> "Last read bit is not updated correctly."); + } +} diff --git a/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java b/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java new file mode 100644 index 0000000..6d15662 --- /dev/null +++ b/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java @@ -0,0 +1,188 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.huffman.HuffmanCoding; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.opentest4j.AssertionFailedError; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Defines the public tests for H12.3.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.3.2 | Huffman-Baum") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_3_2_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "elementsPreState", node -> JsonConverters.toList(node, JsonNode::asInt), + "elementsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "minimumElement", JsonNode::asInt + ); + + @Override + public Class getTestClass() { + return HuffmanCoding.class; + } + + @DisplayName("Die Methode removeMin(Collection elements, Comparator cmp) entfernt das Minimum und gibt diesen korrekt zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_3_2_Tests_testRemoveMin.json", customConverters = CUSTOM_CONVERTERS) + public void testRemoveMin(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("removeMin", Collection.class, Comparator.class); + + // Test setup + List elementsPreState = new ArrayList<>(parameters.get("elementsPreState")); + List elementsPostState = new ArrayList<>(parameters.get("elementsPostState")); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("elements", elementsPreState) + .add("cmp", COMPARATOR) + .build() + ) + .postState( + TestInformation.builder() + .add("elements", elementsPostState) + .build() + ); + + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + List elementsActualState = new ArrayList<>(elementsPreState); + Integer removed = method.invoke(coding, elementsActualState, COMPARATOR); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("elements", elementsPreState) + .build() + ).build(); + + int minimumElement = parameters.getInt("minimumElement"); + Assertions2.assertEquals(minimumElement, removed, context, comment -> "Removed element is incorrect."); + Assertions2.assertEquals(elementsPostState, elementsActualState, context, + comment -> "Remaining elements are incorrect."); + } + + @DisplayName("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) erstellt die Elemente mit der Funktion f korrekt.") + @Test + void testBuildFunctionF() throws Throwable { + // Access method to test + MethodLink method = getMethod("build", Map.class, BiFunction.class, BiFunction.class, Comparator.class); + + // Test setup + Map frequency = Map.of('a', 1, 'b', 2, 'c', 3); + List visited = new ArrayList<>(); + BiFunction f = (c, i) -> { + visited.add(c); + return c; + }; + BiFunction g = (a, b) -> a; + + Context context = testInformation(method).preState( + TestInformation.builder() + .add("frequency", frequency) + .add("f", "f: (Character, Integer) -> Mark character as visited") + .add("g", "g: (Character, Character) -> Character") + .add("cmp", COMPARATOR) + .build() + ).build(); + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + Exception ex = null; + try { + method.invoke(coding, frequency, f, g, COMPARATOR); + } catch (Exception e) { + ex = e; + } + + // Test evaluation + try { + Assertions2.assertEquals(frequency.keySet().stream().toList(), visited, context, + comment -> "Function f was not called with the correct elements."); + } catch (AssertionFailedError e) { + if (ex != null) { + throw ex; + } else { + throw e; + } + } + } + + @DisplayName("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) wendet die Funktion g mit den beiden Minimumelementen korrekt an.") + @Test + void testBuildFunctionG() throws Throwable { + // Access the method to test + MethodLink method = getMethod("build", Map.class, BiFunction.class, BiFunction.class, Comparator.class); + + // Test setup + Map frequency = Map.of('a', 1, 'b', 2, 'c', 3); + List> visited = new ArrayList<>(); + BiFunction f = (c, i) -> c; + BiFunction g = (a, b) -> { + visited.add(Map.entry(a, b)); + return a; + }; + List> expected = List.of(Map.entry('a', 'b'), Map.entry('a', 'c')); + + Context context = testInformation(method).preState( + TestInformation.builder() + .add("frequency", frequency) + .add("f", "f: (Character, Integer) -> Mark pair (Character, Character) as visited") + .add("g", "g: (Character, Character) -> (Character, Character)") + .add("cmp", COMPARATOR) + .build() + ).build(); + + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + Exception ex = null; + try { + method.invoke(coding, frequency, f, g, Comparator.naturalOrder()); + } catch (Exception e) { + ex = e; + } + + // Test evaluation + try { + Assertions2.assertEquals(expected, visited, context, + comment -> "Function g was not called with the correct elements."); + } catch (AssertionFailedError e) { + if (ex != null) { + throw ex; + } else { + throw e; + } + } + } +} diff --git a/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java b/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java new file mode 100644 index 0000000..6afd58a --- /dev/null +++ b/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java @@ -0,0 +1,226 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.EncodingTable; +import h12.io.compress.huffman.HuffmanCodingCompressor; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H12.4.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.4.1 | Huffman-Komprimierung") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_4_1_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "text", JsonNode::asText, + "compressed", node -> JsonConverters.toList(node, JsonNode::asInt), + "encodingTable", JsonConverters::toEncodingTable + ); + + /** + * The compressor instance used for testing. + */ + private @Nullable HuffmanCodingCompressor compressor; + + @AfterEach + void tearDown() throws Exception { + if (compressor != null) { + compressor.close(); + } + } + + @Override + public Class getTestClass() { + return HuffmanCodingCompressor.class; + } + + @DisplayName("Die Methode getText() liest den Text korrekt ein.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testGetText.json", customConverters = CUSTOM_CONVERTERS) + void testGetText(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("getText"); + + // Test setup + String text = parameters.getString("text"); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", text) + .add("out", List.of()) + .build() + ) + .postState( + TestInformation.builder() + .add("out", List.of()) + .build() + ); + + // Test execution + ByteArrayInputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + MockBitOutputStream out = new MockBitOutputStream(); + compressor = new HuffmanCodingCompressor(in, out); + String result = method.invoke(compressor); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("out", out.getBits()) + .build() + ).build(); + + // Validate the output + Assertions2.assertEquals(text, result, context, comment -> "The read text is incorrect."); + } + + @DisplayName("Die Methode computeTextSize(String text, EncodingTable encodingTable) berechnet die Anzahl an Bits, die für die Komprimierung des Textes nötig ist, korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testComputeTextSize.json", customConverters = CUSTOM_CONVERTERS) + void testComputeTextSize(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("computeTextSize", String.class, EncodingTable.class); + + // Test setup + String text = parameters.getString("text"); + EncodingTable encodingTable = parameters.get("encodingTable"); + + Context context = testInformation(method) + .preState( + TestInformation.builder() + .add("text", text) + .add("encodingTable", encodingTable) + .build() + ).build(); + + // Test the method + compressor = new HuffmanCodingCompressor(new ByteArrayInputStream(new byte[0]), new MockBitOutputStream()); + int result = method.invoke(compressor, text, encodingTable); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + int textSize = parameters.getInt("textSize"); + Assertions2.assertEquals(textSize, result, context, comment -> "Computed text size is incorrect."); + } + + @DisplayName("Die Methode encodeContent(String text, EncodingTable encodingTable) komprimiert den Text korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testEncodeText.json", customConverters = CUSTOM_CONVERTERS) + void testEncodeText(JsonParameterSet parameters) throws Throwable { + // Access the method to test + MethodLink method = getMethod("encodeText", String.class, EncodingTable.class); + + // Test setup + String text = parameters.getString("text"); + EncodingTable encodingTable = parameters.get("encodingTable"); + List compressed = parameters.get("compressed"); + InputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + MockBitOutputStream out = new MockBitOutputStream(); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .add("encodingTable", encodingTable) + .add("out", out.getBits()) + .build() + ).postState( + TestInformation.builder() + .add("out", compressed) + .build() + ); + + // Test execution + compressor = new HuffmanCodingCompressor(in, out); + method.invoke(compressor, text, encodingTable); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("out", out.getBits()) + .build() + ).build(); + + Assertions2.assertEquals(compressed, out.getBits(), context, comment -> "The compressed data is incorrect."); + } + + @DisplayName("Die Methode compress() ist vollständig und korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testCompress.json", customConverters = CUSTOM_CONVERTERS) + void testCompress(JsonParameterSet parameters) throws IOException { + // Access method to test + MethodLink method = getMethod("compress"); + + // Test setup + String text = parameters.getString("text"); + EncodingTable encodingTable = parameters.get("encodingTable"); + List compressed = parameters.get("compressed"); + InputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + MockBitOutputStream out = new MockBitOutputStream(); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .add("encodingTable", encodingTable) + .add("out", out.getBits()) + .build() + ).postState( + TestInformation.builder() + .add("out", compressed) + .build() + ); + + // Test execution + compressor = new HuffmanCodingCompressor(in, out); + compressor.compress(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("out", out.getBits()) + .build() + ).build(); + Assertions2.assertTrue(out.isFlushed(), context, + comment -> "The output stream is not flushed."); + Assertions2.assertEquals(compressed, out.getBits(), context, comment -> "The compressed data is incorrect."); + } +} diff --git a/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java b/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java new file mode 100644 index 0000000..7152a1c --- /dev/null +++ b/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java @@ -0,0 +1,18 @@ +package h12; + +import h12.rubric.H12_RubricProvider; + +/** + * A public rubric provider for H12. + * + * @author Nhan Huynh + */ +public class H12_RubricProviderPublic extends H12_RubricProvider { + + /** + * Constructs a new public rubric provider. + */ + public H12_RubricProviderPublic() { + super(true); + } +} diff --git a/H12/src/graderPublic/java/h12/H12_Tests.java b/H12/src/graderPublic/java/h12/H12_Tests.java new file mode 100644 index 0000000..82209f7 --- /dev/null +++ b/H12/src/graderPublic/java/h12/H12_Tests.java @@ -0,0 +1,138 @@ +package h12; + +import h12.assertions.Links; +import h12.assertions.TestConstants; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +/** + * Defines a test skeleton for the H10 assignment. + * + *

Use the following schema: + *

{@code
+ *     public class TestClass extends H12_Test {
+ *
+ *          public static final Map> CUSTOM_CONVERTERS = Map.of(
+ *              ...
+ *          );
+ *
+ *          @Override
+ *          public Class getClassType() {
+ *              return ...
+ *          }
+ *
+ *          @ParameterizedTest
+ *          @JsonParameterSetTest(value = "path-to-json-data.json", customConverters = CUSTOM_CONVERTERS)
+ *          void testXYZ(JsonParameterSet parameters) {
+ *              ...
+ *          }
+ *   }
+ * }
+ * + * @author Nhan Huynh + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@TestForSubmission +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public abstract class H12_Tests { + + /** + * The attribute name for custom converters in the JSON parameter set test annotation. + */ + public static final String CUSTOM_CONVERTERS = "CONVERTERS"; + + /** + * The custom comparator for comparing integers. + */ + public static final Comparator COMPARATOR = new Comparator() { + + private static final Comparator delegate = Comparator.naturalOrder(); + + @Override + public int compare(Integer o1, Integer o2) { + return delegate.compare(o1, o2); + } + + @Override + public String toString() { + return "o1 <= o2"; + } + }; + + /** + * The type of the class under test. + */ + private @Nullable TypeLink type; + + /** + * Configuration for all tests. + */ + @BeforeAll + protected void globalSetup() { + Assertions.assertNotNull( + getClass().getAnnotation(TestForSubmission.class), + "The test class is not annotated with @TestForSubmission which is needed for Jagr to work" + ); + this.type = Links.getType(getTestClass()); + } + + /** + * Returns the class type of the class under test. + * + * @return the class type of the class under test + */ + public abstract Class getTestClass(); + + /** + * Returns the method under test. + * + * @param methodName the name of the method + * @param parameterClasses the parameter classes of the method + * + * @return the method under test + */ + public MethodLink getMethod(String methodName, Class... parameterClasses) { + List parameterTypes = Arrays.stream(parameterClasses).map(BasicTypeLink::of).toList(); + return Links.getMethod( + type, + methodName, + Matcher.of(method -> method.typeList().equals(parameterTypes)) + ); + } + + /** + * Returns the type of the class under test. + * + * @return the type of the class under test + */ + public TypeLink getType() { + if (type == null) { + throw new IllegalStateException("Class of the test method not set"); + } + return type; + } + + /** + * Returns a context builder with the method under test as the subject. + * + * @param methodLink the method under test + * + * @return a context builder with the method under test as the subject + */ + public TestInformation.TestInformationBuilder testInformation(MethodLink methodLink) { + return TestInformation.builder() + .subject(methodLink.reflection()); + } +} diff --git a/H12/src/graderPublic/java/h12/JsonConverters.java b/H12/src/graderPublic/java/h12/JsonConverters.java new file mode 100644 index 0000000..16cc085 --- /dev/null +++ b/H12/src/graderPublic/java/h12/JsonConverters.java @@ -0,0 +1,95 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.io.compress.EncodingTable; +import h12.lang.MyBit; +import h12.lang.MyByte; +import h12.mock.MockBitInputStream; +import h12.mock.MockHuffmanEncodingTable; +import org.jetbrains.annotations.Nullable; + +/** + * Utility class for JSON converters. + * + * @author Nhan Huynh + */ +public final class JsonConverters extends org.tudalgo.algoutils.tutor.general.json.JsonConverters { + + /** + * Prevent instantiation of this utility class. + */ + private JsonConverters() { + + } + + public static @Nullable MyByte toMyByte(JsonNode node) { + + if (!node.isInt() && !node.isNull()) { + throw new IllegalStateException("JSON node is not an integer"); + } + if (node.isNull()) { + return null; + } + return new MyByte(node.asInt()); + } + + /** + * Converts the given JSON node to a bit input stream. + * + * @param node the JSON node to convert + * + * @return the bit input stream + */ + public static MockBitInputStream toBitInputStream(JsonNode node) { + if (!node.isArray()) { + throw new IllegalStateException("JSON node is not an array"); + } + return new MockBitInputStream(toList(node, JsonNode::asInt)); + } + + /** + * Converts the given JSON node to an encoding table. + * + * @param node the JSON node to convert + * + * @return the encoding table + */ + public static EncodingTable toEncodingTable(JsonNode node) { + if (!node.isObject()) { + throw new IllegalStateException("JSON node is not an object"); + } + return new MockHuffmanEncodingTable(toMap(node, keyMapper -> keyMapper.charAt(0), JsonNode::asText)); + } + + /** + * Converts a JSON node to a byte array. + * + * @param node the JSON node containing the bytes + * + * @return the byte array + */ + public static byte[] toByteArray(JsonNode node) { + if (!node.isArray()) { + throw new IllegalStateException("JSON node is not an array"); + } + byte[] bytes = new byte[node.size()]; + for (int i = 0; i < node.size(); i++) { + bytes[i] = (byte) node.get(i).asInt(); + } + return bytes; + } + + /** + * Converts a JSON node to a bit + * + * @param node the JSON node containing the bit + * + * @return the bit + */ + public static MyBit toBit(JsonNode node) { + if (!node.isInt()) { + throw new IllegalStateException("JSON node is not an int"); + } + return MyBit.fromInt(node.asInt()); + } +} diff --git a/H12/src/graderPublic/java/h12/TestInformation.java b/H12/src/graderPublic/java/h12/TestInformation.java new file mode 100644 index 0000000..33f2cec --- /dev/null +++ b/H12/src/graderPublic/java/h12/TestInformation.java @@ -0,0 +1,234 @@ +package h12; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.assertions.Property; +import org.tudalgo.algoutils.tutor.general.assertions.basic.BasicProperty; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.ListIterator; + +/** + * Context information for a test. THis class extends the {@link Context} interface and provide optional pre-, post- and + * actual states of the test. + * + * @author Nhan Huynh + */ +public class TestInformation implements Context { + + /** + * The subject of the test. + */ + private final @Nullable Object subject; + + /** + * The properties of the test. + */ + private final Collection properties; + + /** + * Constructs new test information with the specified subject and properties. + * + * @param subject the subject of the test + * @param preState the pre-state of the test + * @param postState the post-state of the test + * @param actualState the actual state of the test + * @param properties the properties of the test + */ + public TestInformation( + @Nullable Object subject, + @Nullable TestInformation preState, + @Nullable TestInformation postState, + @Nullable TestInformation actualState, + Collection properties) { + + + Context.Builder builder = Assertions2.contextBuilder() + .subject(subject); + + if (preState != null) { + addState(builder, "Pre state", preState); + } + if (postState != null) { + addState(builder, "Post state", postState); + } + if (actualState != null) { + addState(builder, "Actual state", actualState); + } + builder.add(properties.toArray(Property[]::new)); + Context context = builder.build(); + this.subject = context.subject(); + this.properties = context.properties(); + } + + /** + * Adds the state to the builder. + * + * @param builder the builder to add the sotate to + * @param name the name of the state + * @param state the state to add + */ + private void addState(Builder builder, String name, TestInformation state) { + if (state != null) { + builder.add( + name, + Assertions2.contextBuilder() + .add(state.properties.toArray(Property[]::new)) + .build() + ); + } + } + + /** + * Returns a new test information builder. + * + * @return a new test information builder + */ + public static TestInformationBuilder builder() { + return new TestInformationBuilderImpl(); + } + + @Override + public Object subject() { + return subject; + } + + @Override + public Collection properties() { + return properties; + } + + /** + * Builder for {@link TestInformation}. + */ + public interface TestInformationBuilder extends h12.rubric.Builder { + + /** + * Sets the subject of the test. + * + * @param subject the subject of the test + * + * @return this builder after setting the subject + */ + TestInformationBuilder subject(Object subject); + + /** + * Sets the pre-state of the test. + * + * @param preState the pre-state of the test + * + * @return this builder after setting the pre-state + */ + TestInformationBuilder preState(TestInformation preState); + + /** + * Sets the post-state of the test. + * + * @param postState the post-state of the test + * + * @return this builder after setting the post-state + */ + TestInformationBuilder postState(TestInformation postState); + + /** + * Sets the actual state of the test. + * + * @param actualState the actual state of the test + * + * @return this builder after setting the actual state + */ + TestInformationBuilder actualState(TestInformation actualState); + + /** + * Adds a property to the test which provides context information. + * + * @param key the key of the property + * @param value the value of the property + * + * @return this builder after adding the property + */ + TestInformationBuilder add(String key, Object value); + } + + /** + * Implementation of the {@link TestInformationBuilder} interface. + */ + private static class TestInformationBuilderImpl implements TestInformationBuilder { + + /** + * The subject of the test. + */ + private @Nullable Object subject; + + /** + * The pre-state of the test. + */ + private @Nullable TestInformation preState = null; + + /** + * The post-state of the test. + */ + private @Nullable TestInformation postState = null; + + /** + * The actual state of the test. + */ + private @Nullable TestInformation actualState = null; + + /** + * The properties of the test. + */ + private final List properties = new ArrayList<>(); + + @Override + public TestInformationBuilder subject(Object subject) { + this.subject = subject; + return this; + } + + @Override + public TestInformationBuilder preState(TestInformation preState) { + this.preState = preState; + return this; + } + + @Override + public TestInformationBuilder postState(TestInformation postState) { + this.postState = postState; + return this; + } + + @Override + public TestInformationBuilder actualState(TestInformation actualState) { + this.actualState = actualState; + return this; + } + + @Override + public TestInformationBuilder add(String key, Object value) { + ListIterator iterator = properties.listIterator(); + while (iterator.hasNext()) { + Property property = iterator.next(); + if (property.key().equals(key)) { + iterator.set(new BasicProperty(key, value)); + return this; + } + } + properties.add(new BasicProperty(key, value)); + return this; + } + + @Override + public TestInformation build() { + return new TestInformation( + subject, + preState, + postState, + actualState, + properties); + } + } +} diff --git a/H12/src/graderPublic/java/h12/assertions/Links.java b/H12/src/graderPublic/java/h12/assertions/Links.java new file mode 100644 index 0000000..cae0faa --- /dev/null +++ b/H12/src/graderPublic/java/h12/assertions/Links.java @@ -0,0 +1,80 @@ +package h12.assertions; + +import org.tudalgo.algoutils.tutor.general.assertions.Assertions3; +import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.match.MatcherFactories; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; + +/** + * Utility class for links to classes and methods. + * + * @author Nhan Huynh + */ +public final class Links { + + /** + * Matcher factory for string matchers. + */ + private static final MatcherFactories.StringMatcherFactory STRING_MATCHER_FACTORY = BasicStringMatchers::identical; + + /** + * Prevent instantiation of this utility class. + */ + private Links() { + + } + + /** + * Returns the type link for the given class. + * + * @param clazz the class to get the type from + * + * @return the type link for the given class + */ + public static TypeLink getType(Class clazz) { + return Assertions3.assertTypeExists( + BasicPackageLink.of(clazz.getPackageName()), + STRING_MATCHER_FACTORY.matcher(clazz.getSimpleName()) + ); + } + + /** + * Returns the field link for the given type and field name. + * + * @param type the type to get the field from + * @param methodName the name of the field + * @param matchers the matchers for additional checks to retrieve the field + * + * @return the field link for the given type and field name + */ + @SafeVarargs + public static FieldLink getField(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertFieldExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the method link for the given type and method name. + * + * @param type the type to get the method from + * @param methodName the name of the method + * @param matchers the matchers for additional checks to retrieve the method + * + * @return the method link for the given type and method name + */ + @SafeVarargs + public static MethodLink getMethod(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertMethodExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } +} diff --git a/H12/src/graderPublic/java/h12/assertions/TestConstants.java b/H12/src/graderPublic/java/h12/assertions/TestConstants.java new file mode 100644 index 0000000..70d9791 --- /dev/null +++ b/H12/src/graderPublic/java/h12/assertions/TestConstants.java @@ -0,0 +1,25 @@ +package h12.assertions; + +/** + * Constants for tests for configuring test behavior. + * + * @author Nhan Huynh + */ +public final class TestConstants { + + /** + * Timeout for tests in seconds. + */ + public static final int TEST_TIMEOUT_IN_SECONDS = 2; + + /** + * Skip after the first failed test. + */ + public static final boolean SKIP_AFTER_FIRST_FAILED_TEST = true; + + /** + * Prevent instantiation of this utility class. + */ + private TestConstants() { + } +} diff --git a/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java b/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java new file mode 100644 index 0000000..ba47d63 --- /dev/null +++ b/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java @@ -0,0 +1,105 @@ +package h12.mock; + +import h12.io.BitInputStream; +import h12.lang.MyBit; +import h12.lang.MyByte; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.IntStream; + +/** + * A mock bit input stream for testing purposes. This implementation allows us to define which bits to read. + * + * @author Nhan Huynh + */ +public class MockBitInputStream extends BitInputStream { + + /** + * The bits to read. + */ + private final List bits; + + /** + * The iterator for reading the bits. + */ + private Iterator read; + + /** + * Creates a new mock bit input stream with the given bits. + * + * @param bits the bits to read + */ + public MockBitInputStream(List bits) { + this.bits = bits; + this.read = bits.iterator(); + } + + /** + * Creates a new mock bit input stream with the given bits. + * + * @param bits the bits to read + */ + public MockBitInputStream(Integer... bits) { + this(Arrays.asList(bits)); + } + + @Override + public int readBit() throws IOException { + if (!read.hasNext()) { + return -1; + } + return read.next(); + } + + @Override + public int read() throws IOException { + if (!read.hasNext()) { + return -1; + } + MyByte value = new MyByte(); + int low = 0; + int high = MyByte.NUMBER_OF_BITS - 1; + IntStream.rangeClosed(low, high).forEach(i -> value.set(high - i, MyBit.fromInt(read.next()))); + return value.intValue(); + } + + /** + * Returns the bits that this mock bit input stream can read. + * + * @return the bits that this mock bit input stream can read + */ + public List getBits() { + return bits; + } + + /** + * Returns the remaining bits that this mock bit input stream can read. + * + * @return the remaining bits that this mock bit input stream can read + */ + public List getRemainingBits() { + List remainingBits = new ArrayList<>(); + read.forEachRemaining(remainingBits::add); + setRemainingBits(remainingBits); + return remainingBits; + } + + /** + * Sets the remaining bits that this mock bit input stream can read. + * + * @param elements the remaining bits to read + */ + public void setRemainingBits(Iterable elements) { + this.read = elements.iterator(); + } + + @Override + public String toString() { + return bits.toString(); + } +} + diff --git a/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java b/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java new file mode 100644 index 0000000..fa2d2bb --- /dev/null +++ b/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java @@ -0,0 +1,84 @@ +package h12.mock; + +import h12.io.BitOutStream; +import h12.lang.MyBit; +import h12.lang.MyByte; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A mock bit output stream for testing purposes. This implementation allows us to access the written bits directly. + * + * @author Nhan Huynh + */ +public class MockBitOutputStream extends BitOutStream { + + /** + * The bits written to the stream. + */ + private final List bits = new ArrayList<>(); + + /** + * Whether the stream has been flushed. + */ + private boolean flushed; + + @Override + public void writeBit(MyBit bit) throws IOException { + bits.add(bit.intValue()); + } + + @Override + public void write(int b) throws IOException { + MyByte value = new MyByte(b); + for (int i = MyByte.NUMBER_OF_BITS - 1; i >= 0; i--) { + bits.add(value.get(i).intValue()); + } + } + + /** + * Returns the bits written to the stream. + * + * @return the bits written to the stream + */ + public List getBits() { + if (!flushed) { + return List.of(); + } + return bits; + } + + /** + * Returns whether the stream has been flushed. + * + * @return whether the stream has been flushed + */ + public boolean isFlushed() { + return flushed; + } + + @Override + public void flush() throws IOException { + super.flush(); + flushed = true; + } + + @Override + public void close() throws IOException { + super.close(); + flush(); + } + + @Override + public int hashCode() { + return Objects.hashCode(getBits()); + } + + @Override + public String toString() { + return bits.toString(); + } +} diff --git a/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java b/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java new file mode 100644 index 0000000..00bd9bf --- /dev/null +++ b/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java @@ -0,0 +1,82 @@ +package h12.mock; + +import h12.io.compress.EncodingTable; + +import java.util.Map; +import java.util.Objects; +import java.util.stream.StreamSupport; + +/** + * A mock implementation of the {@link EncodingTable} interface for testing purposes. + * + * @author Nhan Huynh + */ +public class MockHuffmanEncodingTable implements EncodingTable { + + /** + * The encodings of characters. + */ + private final Map encodings; + + /** + * Creates a new mock encoding table with the given encodings. + * + * @param encodings the encodings of characters + */ + public MockHuffmanEncodingTable(Map encodings) { + this.encodings = encodings; + } + + @Override + public boolean containsCharacter(Character character) { + return encodings.containsKey(character); + } + + @Override + public boolean containsCode(String code) { + return encodings.containsValue(code); + } + + @Override + public boolean containsCode(Iterable iterable) { + return containsCode(StreamSupport.stream(iterable.spliterator(), false) + .map(String::valueOf) + .reduce("", String::concat)); + } + + @Override + public String getCode(Character character) { + return encodings.get(character); + } + + @Override + public Character getCharacter(String code) { + return encodings.entrySet().stream() + .filter(entry -> entry.getValue().equals(code)) + .map(Map.Entry::getKey) + .findFirst() + .orElseThrow(); + } + + @Override + public Character getCharacter(Iterable iterable) { + return getCharacter(StreamSupport.stream(iterable.spliterator(), false) + .map(String::valueOf) + .reduce("", String::concat)); + } + + @Override + public boolean equals(Object o) { + return this == o || o instanceof MockHuffmanEncodingTable that && encodings.equals(that.encodings); + } + + @Override + public int hashCode() { + return Objects.hashCode(encodings); + } + + @Override + public String toString() { + return encodings.toString(); + } +} diff --git a/H12/src/graderPublic/java/h12/rubric/Builder.java b/H12/src/graderPublic/java/h12/rubric/Builder.java new file mode 100644 index 0000000..901f4e5 --- /dev/null +++ b/H12/src/graderPublic/java/h12/rubric/Builder.java @@ -0,0 +1,18 @@ +package h12.rubric; + +/** + * A builder interface for building objects. + * + * @param the type of object to build + * + * @author Nhan Huynh + */ +public interface Builder { + + /** + * Builds the object. + * + * @return the built object + */ + T build(); +} diff --git a/H12/src/graderPublic/java/h12/rubric/Criteriable.java b/H12/src/graderPublic/java/h12/rubric/Criteriable.java new file mode 100644 index 0000000..e98659d --- /dev/null +++ b/H12/src/graderPublic/java/h12/rubric/Criteriable.java @@ -0,0 +1,19 @@ +package h12.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; + +/** + * An object that implements this interface indicates that it can be converted to a {@link Criterion} which means + * it is gradable. + * + * @author Nhan Huynh + */ +public interface Criteriable { + + /** + * Returns the criterion that represents this object. + * + * @return the criterion that represents this object + */ + Criterion getCriterion(); +} diff --git a/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java b/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java new file mode 100644 index 0000000..25435d6 --- /dev/null +++ b/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java @@ -0,0 +1,192 @@ +package h12.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Provides the rubric for H10. + * + * @author Nhan Huynh + */ +public abstract class H12_RubricProvider implements RubricProvider { + + /** + * Defines the subtask H12.1.1 for task H12.1. + */ + private static final Subtask H12_1_1 = Subtask.builder() + .description("H12.1.1 | Bits lesen") + .testClassName("h12.H12_1_1_Tests") + .criterion("Die Methode fetch() aktualisiert den Puffer und die Position korrekt.", Map.of( + "testFetchNotEOF", List.of(JsonParameterSet.class), + "testFetchEOF", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode readBit() liest das nächste Byte korrekt, falls wir bereits alle Bits des vorherigen Bytes gelesen haben", "testReadBitNextByte", JsonParameterSet.class) + .criterion("Die Methode readBit() gibt in allen anderen Fällen das korrekte Bit zurück.", Map.of( + "testReadBitByteStart", List.of(JsonParameterSet.class), + "testReadBitByteMiddle", List.of(JsonParameterSet.class), + "testReadBitByteEnd", List.of(JsonParameterSet.class), + "testReadBitEOF", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode read() gibt das korrekte Ergebnis zurück, falls wir am Ende des Streams sind.", "testReadEnd", JsonParameterSet.class) + .criterion("Die Methode read() gibt das korrekte Teilergebnis zurück, falls der Stream keine 8 Bits mehr enthält.", "testReadPartial", JsonParameterSet.class) + .criterion("Die Methode read() gibt in allen anderen Fallen das korrekte Ergebnis zurück.", "testRead", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.1.2 for task H12.1. + */ + private static final Subtask H12_1_2 = Subtask.builder() + .description("H12.1.2 | Bits schreiben") + .testClassName("h12.H12_1_2_Tests") + .criterion("Die Methode flushBuffer() aktualisiert den Puffer und Position korrekt, wenn nötig.", false, Map.of( + "testFlushBufferUpdateYes", List.of(JsonParameterSet.class), + "testFlushBufferUpdateNo", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode flushBuffer() schreibt das Zeichen in den internen OutputStream korrekt.", false, "testFlushBufferWrite", JsonParameterSet.class) + .criterion("Die Methode writeBit(Bit bit) schreibt das Zeichen in den internen OutputStream, falls der Puffer voll ist.", false, Map.of( + "testWriteBitFlushYes", List.of(JsonParameterSet.class), + "testWriteBitFlushNo", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode writeBit(Bit bit) schreibt ein Bit korrekt.", false, "testWriteBit", JsonParameterSet.class) + .criterion("Die Methode write(int b) schreibt ein Byte korrekt.", false, "testWrite", JsonParameterSet.class) + .criterion("Die Methode write(int b) wirft eine IllegalArgumentException, falls die Eingabe kein Byte ist.", false, "testWriteIllegalArgumentException", JsonParameterSet.class) + .build(); + + /** + * Defines the task H12.1. + */ + private static final Task H12_1 = Task.builder() + .description("H12.1 | Mit Bits jonglieren: Eingabe und Ausgabe im Detail") + .subtasks(H12_1_1, H12_1_2) + .build(); + + /** + * Defines the subtask H12.2.1 for task H12.2. + */ + private static final Subtask H12_2_1 = Subtask.builder() + .description("H12.2.1 | BitRunningLengthCompressor") + .testClassName("h12.H12_2_1_Tests") + .criterion("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits nicht maximal ist.", "testGetBitCountNotMax", JsonParameterSet.class) + .criterion("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits maximal ist.", "testGetBitCountMax", JsonParameterSet.class) + .criterion("Die Methode compress() komprimiert korrekt.", "testCompress", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.2.2 for task H12.2. + */ + private static final Subtask H12_2_2 = Subtask.builder() + .description("H12.2.2 | BitRunningLengthDecompressor") + .testClassName("h12.H12_2_2_Tests") + .criterion("Die Methode writeBit(int count, Bit bit) schreibt die Anzahl an aufeinanderfolgenden wiederholenden Bits korrekt.", false, "testWriteBit", JsonParameterSet.class) + .criterion("Die Methode decompress() liest die Anzahl an aufeinanderfolgenden wiederholenden Bits.", false, "testDecompressBitCount", JsonParameterSet.class) + .criterion("Die Methode decompress() dekomprimiert korrekt.", false, "testDecompress", JsonParameterSet.class) + .build(); + + /** + * Defines the task H12.2. + */ + private static final Task H12_2 = Task.builder() + .description("H12.3 | My Heart Skips Skips Skips, Skips Skips Skips a Bit") + .subtasks(H12_2_1, H12_2_2) + .build(); + + /** + * Defines the subtask H12.3.1 for task H12.3. + */ + private static final Subtask H12_3_1 = Subtask.builder() + .description("H12.3.1 | Häufigkeitstabelle") + .testClassName("h12.H12_3_1_Tests") + .criterion("Die Methode buildFrequencyTable(String text) erstellt die Häufigkeitstabelle mit allen Zeichen als Schlüssel korrekt.", false, "testBuildFrequencyTableKeys", JsonParameterSet.class) + .criterion("Die Methode buildFrequencyTable(String text) erstellt die Häufigkeitstabelle mt den Häufigkeiten korrekt.", false, "testResult", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.3.2 for task H12.3. + */ + private static final Subtask H12_3_2 = Subtask.builder() + .description("H12.3.2 | Huffman-Baum") + .testClassName("h12.H12_3_2_Tests") + .criterion("Die Methode removeMin(Collection elements, Comparator cmp) entfernt das Minimum und gibt diesen korrekt zurück.", "testRemoveMin", JsonParameterSet.class) + .criterion("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) erstellt die Elemente mit der Funktion f korrekt.", "testBuildFunctionF") + .criterion("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) wendet die Funktion g mit den beiden Minimumelementen korrekt an.", "testBuildFunctionG") + .criterion("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) ist vollständig und korrekt.", false, "testResult") + .build(); + + /** + * Defines the task H12.3. + */ + private static final Task H12_3 = Task.builder() + .description("H12.3 | Die Kunst des Codes: Huffman-Coding I") + .subtasks(H12_3_1, H12_3_2) + .build(); + + /** + * Defines the subtask H12.4.1 for task H12.4. + */ + private static final Subtask H12_4_1 = Subtask.builder() + .description("H12.4.1 | Huffman-Komprimierung") + .testClassName("h12.H12_4_1_Tests") + .criterion("Die Methode getText() liest den Text korrekt ein.", "testGetText", JsonParameterSet.class) + .criterion("Die Methode computeTextSize(String text, EncodingTable encodingTable) berechnet die Anzahl an Bits, die für die Komprimierung des Textes nötig ist, korrekt.", "testComputeTextSize", JsonParameterSet.class) + .criterion("Die Methode encodeText(String text, EncodingTable encodingTable) komprimiert den Text korrekt.", "testEncodeText", JsonParameterSet.class) + .criterion("Die Methode compress() ist vollständig und korrekt.", "testCompress", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.4.2 for task H12.2. + */ + private static final Subtask H12_4_2 = Subtask.builder() + .description("H12.4.2 | Huffman-Dekomprimierung") + .testClassName("h12.H12_4_2_Tests") + .criterion("Die Methode skipBits() überspringt die Füllbits korrekt.", false, "testSkipBits", JsonParameterSet.class) + .criterion("Die Methode decodeCharacter(int startBit, EncodingTable encodingTable) dekomprimiert einen Zeichen korrekt.", false, "testDecodeCharacter", JsonParameterSet.class) + .criterion("Die Methode decodeText(EncodingTable encodingTable) Dekomprimiert den Text korrekt.", false, "testDecodeText", JsonParameterSet.class) + .criterion("Die Methode decompress() ist vollständig und korrekt.", false, "testDecompress", JsonParameterSet.class) + .build(); + + /** + * Defines the task H12.4. + */ + private static final Task H12_4 = Task.builder() + .description("H12.4 | Die Kunst des Codes: Huffman-Coding II") + .subtasks(H12_4_1, H12_4_2) + .build(); + + /** + * Whether the private tests are being graded. + */ + private final boolean publicTests; + + /** + * Constructs a new rubric provider. + * + * @param publicTests whether the private tests are being graded + */ + public H12_RubricProvider(boolean publicTests) { + this.publicTests = publicTests; + } + + /** + * Constructs a new public rubric provider. + */ + public H12_RubricProvider() { + this(true); + } + + @Override + public Rubric getRubric() { + return Rubric.builder() + .title("H12 | Datenkomprimierung - %s Tests".formatted(publicTests ? "Public" : "Private")) + .addChildCriteria( + Stream.of(H12_1, H12_2, H12_3, H12_4) + .map(Task::getCriterion) + .toArray(Criterion[]::new) + ).build(); + } +} diff --git a/H12/src/graderPublic/java/h12/rubric/Subtask.java b/H12/src/graderPublic/java/h12/rubric/Subtask.java new file mode 100644 index 0000000..29086c9 --- /dev/null +++ b/H12/src/graderPublic/java/h12/rubric/Subtask.java @@ -0,0 +1,324 @@ +package h12.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Gradable; +import org.sourcegrade.jagr.api.rubric.Grader; +import org.sourcegrade.jagr.api.rubric.JUnitTestRef; +import org.tudalgo.algoutils.tutor.general.jagr.RubricUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/** + * Represents a subtask in a rubric. + * + * @param description a short description of the subtask + * @param criteria the subtasks that must be met to complete the subtask + * @param requirements the requirements that must be met to complete the subtask + * + * @author Nhan Huynh + */ +public record Subtask( + String description, + List criteria, + List requirements +) implements Criteriable { + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + * + * @return a new subtask builder + */ + public static SubtaskBuilder builder() { + return new SubtaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .minPoints(0) + .addChildCriteria(Stream.concat(criteria.stream(), requirements.stream()).toArray(Criterion[]::new)) + .build(); + } + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + */ + public interface SubtaskBuilder extends Builder { + + /** + * Sets the description of the subtask. + * + * @param description the description of the subtask + * + * @return this builder instance with the description set + */ + SubtaskBuilder description(String description); + + /** + * Sets the name of the test class that tests this subtask. + * + * @param testClassName the name of the test class that tests this subtask + * + * @return this builder instance with the test class name set + */ + SubtaskBuilder testClassName(String testClassName); + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the criterion added + */ + SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ); + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, Map>> testMethodsSignature) { + return criterion(description, true, testMethodsSignature); + } + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion( + String description, + boolean publicTest, + String testMethodName, + Class... testMethodParameters + ) { + return criterion(description, publicTest, Map.of(testMethodName, List.of(testMethodParameters))); + } + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodName the name of the test method + * @param testMethodSignature the signature of the test method + * + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, String testMethodName, Class... testMethodSignature) { + return criterion(description, true, testMethodName, testMethodSignature); + } + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the requirement added + */ + SubtaskBuilder requirement(String description, Map>> testMethodsSignature); + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * + * @return this builder instance with the requirement added + */ + default SubtaskBuilder requirement(String description, String testMethodName, Class... testMethodParameters) { + return requirement(description, Map.of(testMethodName, List.of(testMethodParameters))); + } + } + + /** + * A builder for building {@link Subtask} instances. + */ + private static class SubtaskCriteriaBuilderImpl implements SubtaskBuilder { + + /** + * The description of the subtask. + */ + private @NotNull String description = ""; + + /** + * The name of the test class that tests this subtask. + */ + private @NotNull String testClassName = ""; + + /** + * The subtasks of the subtask. + */ + private final List> criteria = new ArrayList<>(); + + /** + * The requirements of the subtask. + */ + private final List> requirements = new ArrayList<>(); + + @Override + public SubtaskBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public SubtaskBuilder testClassName(String testClassName) { + this.testClassName = testClassName; + return this; + } + + /** + * Returns the description of the subtask. + * + * @return the description of the subtask + */ + private @NotNull String getDescription() { + return description; + } + + /** + * Returns a pre-configured criterion builder where the description and grader are set. + * + * @param description the description of the criterion + * @param grader the grader of the criterion + * + * @return a pre-configured criterion builder with the description and grader set + */ + private Criterion.Builder criterionBuilder(String description, Grader grader) { + return Criterion.builder() + .shortDescription(description) + .grader(grader); + } + + /** + * Returns a pre-configured criterion builder where the description and test reference are set. + * + * @param description the description of the criterion + * @param testRef the test reference of the criterion + * + * @return a pre-configured criterion builder with the description and test reference set + */ + private Criterion.Builder criterionBuilder(String description, JUnitTestRef testRef) { + return criterionBuilder( + description, + Grader.testAwareBuilder() + .requirePass(testRef) + .pointsFailedMin() + .pointsPassedMax() + .build() + ); + } + + /** + * Creates a criterion supplier with the given description, class name, test methods signature, and points. + * Since the points can only be determined after all subtasks are added, the points are calculated lazily. + * + * @param description the description of the criterion + * @param className the name of the test class that tests this subtask + * @param testMethodsSignature the signature of the test methods + * @param points the points of the criterion + * + * @return a criterion supplier with the given description, class name, test methods signature, and points + */ + private Supplier criterion( + String description, + String className, + Map>> testMethodsSignature, + Supplier points + ) { + return () -> { + Criterion.Builder builder; + try { + List testRefs = new ArrayList<>(testMethodsSignature.size()); + for (Map.Entry>> entry : testMethodsSignature.entrySet()) { + Method method = Class.forName(className).getDeclaredMethod( + entry.getKey(), + entry.getValue().toArray(Class[]::new) + ); + testRefs.add(JUnitTestRef.ofMethod(method)); + } + builder = criterionBuilder(description, JUnitTestRef.and(testRefs.toArray(JUnitTestRef[]::new))); + } catch (Exception e) { + builder = criterionBuilder(description, RubricUtils.graderPrivateOnly()); + } + int pointsValue = points.get(); + if (pointsValue >= 0) { + builder.minPoints(0); + builder.maxPoints(pointsValue); + } else { + builder.maxPoints(0); + builder.minPoints(pointsValue); + } + return builder.build(); + }; + } + + @Override + public SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ) { + criteria.add( + criterion( + description, + testClassName + (publicTest ? "Public" : "Private"), + testMethodsSignature, + () -> 1 + ) + ); + return this; + } + + @Override + public SubtaskBuilder requirement(String description, Map>> testMethodsSignature) { + requirements.add( + criterion( + description, + testClassName + "Private", + testMethodsSignature, + () -> -criteria.stream() + .map(Supplier::get) + .mapToInt(Gradable::getMaxPoints) + .sum() + ) + ); + return this; + } + + @Override + public Subtask build() { + if (testClassName.isBlank()) { + throw new IllegalStateException("Test class name cannot be blank!"); + } + return new Subtask( + description, + criteria.stream().map(Supplier::get).toList(), + requirements.stream().map(Supplier::get).toList() + ); + } + } +} diff --git a/H12/src/graderPublic/java/h12/rubric/Task.java b/H12/src/graderPublic/java/h12/rubric/Task.java new file mode 100644 index 0000000..33c2022 --- /dev/null +++ b/H12/src/graderPublic/java/h12/rubric/Task.java @@ -0,0 +1,106 @@ +package h12.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a task in a rubric. + * + * @param description a short description of the task + * @param subtasks the subtasks that must be met to complete the task + * + * @author Nhan Huynh + */ +public record Task(String description, List subtasks) implements Criteriable { + + /** + * Returns a new {@link TaskCriteriaBuilder} to build a {@link Task}. + * + * @return a new task subtasks builder + */ + public static TaskCriteriaBuilder builder() { + return new TaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .addChildCriteria(subtasks.stream().map(Subtask::getCriterion).toArray(Criterion[]::new)) + .build(); + } + + /** + * + */ + public interface TaskCriteriaBuilder extends Builder { + + /** + * Sets the description of the task. + * + * @param description the description of the task + * + * @return this builder instance with the description set + */ + TaskCriteriaBuilder description(String description); + + /** + * Adds subtasks to the task. + * + * @param subtasks the subtasks to add + * + * @return this builder instance with the subtasks added + */ + TaskCriteriaBuilder subtasks(Subtask... subtasks); + + /** + * Adds a criterion to the task. + * + * @param criterion the criterion to add + * + * @return this builder instance with the criterion added + */ + default TaskCriteriaBuilder subtask(Subtask criterion) { + return subtasks(criterion); + } + } + + /** + * A builder for building {@link Task} instances. + */ + private static class TaskCriteriaBuilderImpl implements TaskCriteriaBuilder { + + /** + * The description of the task. + */ + private @NotNull String description = ""; + + /** + * The subtasks of the task. + */ + private final List criteria = new ArrayList<>(); + + @Override + public TaskCriteriaBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public TaskCriteriaBuilder subtasks(Subtask... subtasks) { + this.criteria.addAll(List.of(subtasks)); + return this; + } + + @Override + public Task build() { + if (description.isBlank()) { + throw new IllegalArgumentException("Description cannot be blank!"); + } + return new Task(description, criteria); + } + } +} diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json b/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json new file mode 100644 index 0000000..ab3e53b --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json @@ -0,0 +1,12 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json b/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json new file mode 100644 index 0000000..7ab7cc0 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json @@ -0,0 +1,36 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1 + ], + "bufferPostState": 215, + "positionPostState": 7 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json b/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json new file mode 100644 index 0000000..be4ca2f --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json @@ -0,0 +1,115 @@ +[ + { + "bitsPreState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": 7, + "bitsPostState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPostState": 69, + "positionPostState": -1, + "expectedByte": 69 + }, + { + "bitsPreState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": 3, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPostState": 178, + "positionPostState": 0, + "expectedByte": 91 + }, + { + "bitsPreState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": 0, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPostState": 178, + "positionPostState": 0, + "expectedByte": 217 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json new file mode 100644 index 0000000..2e06ff4 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json @@ -0,0 +1,45 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": 69, + "positionPostState": -1, + "expectedBit": 1 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json new file mode 100644 index 0000000..0e57973 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json @@ -0,0 +1,45 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": 3, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": 69, + "positionPostState": 2, + "expectedBit": 0 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json new file mode 100644 index 0000000..7a1e456 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json @@ -0,0 +1,45 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": 7, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": 69, + "positionPostState": 6, + "expectedBit": 0 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json new file mode 100644 index 0000000..6d70391 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json @@ -0,0 +1,13 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1, + "expectedBit": -1 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json new file mode 100644 index 0000000..814894d --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json @@ -0,0 +1,72 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": null, + "positionPostState": 7, + "expectedBit": 1 + }, + { + "bitsPreState": [ + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": null, + "positionPostState": 7, + "expectedBit": 0 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json new file mode 100644 index 0000000..b801b91 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json @@ -0,0 +1,13 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1, + "expectedByte": -1 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json b/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json new file mode 100644 index 0000000..62cc217 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json @@ -0,0 +1,13 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": 3, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1, + "expectedByte": 80 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json b/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json new file mode 100644 index 0000000..e6fb409 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json @@ -0,0 +1,349 @@ +[ + { + "bitsPreState": [ + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [], + "counts": [], + "compressedBits": [] + }, + { + "bitsPreState": [ + 0 + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [ + 0 + ], + "counts": [ + 1 + ], + "compressedBits": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "bitsPreState": [ + 1 + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [ + 1 + ], + "counts": [ + 1 + ], + "compressedBits": [ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [ + 0, + 1, + 0, + 0, + 1 + ], + "counts": [ + 5, + 1, + 127, + 62, + 26 + ], + "compressedBits": [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0 + ] + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json b/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json new file mode 100644 index 0000000..660199b --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json @@ -0,0 +1,560 @@ +[ + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPostState": 0, + "bit": 0, + "count": 127 + }, + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPreState": 1, + "bitsPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPostState": 1, + "bit": 1, + "count": 127 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json b/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json new file mode 100644 index 0000000..45adea2 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json @@ -0,0 +1,516 @@ +[ + { + "bitsPreState": [ + ], + "lastReadPreState": 0, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "bit": 0, + "count": 1 + }, + { + "bitsPreState": [ + ], + "lastReadPreState": 1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "bit": 1, + "count": 1 + }, + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPostState": 1, + "bit": 0, + "count": 126 + }, + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPreState": 1, + "bitsPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPostState": 0, + "bit": 1, + "count": 126 + }, + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPostState": 1, + "bit": 0, + "count": 71 + }, + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPreState": 1, + "bitsPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPostState": 0, + "bit": 1, + "count": 71 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json b/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json new file mode 100644 index 0000000..0dbb4e6 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json @@ -0,0 +1,118 @@ +[ + { + "elementsPreState": [ + 1 + ], + "elementsPostState": [ + ], + "minimumElement": 1 + }, + { + "elementsPreState": [ + 2, + 3 + ], + "elementsPostState": [ + 3 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 2, + 1 + ], + "elementsPostState": [ + 2 + ], + "minimumElement": 1 + }, + { + "elementsPreState": [ + 2, + 4, + 3, + 7, + 2, + 6, + 54 + ], + "elementsPostState": [ + 4, + 3, + 7, + 2, + 6, + 54 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 4, + 3, + 7, + 2, + 6, + 54, + 2 + ], + "elementsPostState": [ + 4, + 3, + 7, + 6, + 54, + 2 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 5, + 3, + 7, + 2, + 6, + 54, + 2 + ], + "elementsPostState": [ + 5, + 3, + 7, + 6, + 54, + 2 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ], + "elementsPostState": [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ], + "minimumElement": 2 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json b/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json new file mode 100644 index 0000000..01cb9ec --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json @@ -0,0 +1,17458 @@ +[ + { + "text": "H", + "encodingTable": { + "H": "1" + }, + "compressed": [ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1 + ] + }, + { + "text": "Hello, World!", + "encodingTable": { + " ": "1010", + "!": "1011", + "r": "1100", + "d": "1101", + "e": "1110", + "W": "1111", + "H": "000", + ",": "001", + "l": "01", + "o": "100" + }, + "compressed": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1 + ] + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "compressed": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ] + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json b/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json new file mode 100644 index 0000000..19b910d --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json @@ -0,0 +1,79 @@ +[ + { + "text": "H", + "encodingTable": { + "H": "1" + }, + "textSize": 1 + }, + { + "text": "Hello, World!", + "encodingTable": { + " ": "1010", + "!": "1011", + "r": "1100", + "d": "1101", + "e": "1110", + "W": "1111", + "H": "000", + ",": "001", + "l": "01", + "o": "100" + }, + "textSize": 42 + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "textSize": 15297 + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json b/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json new file mode 100644 index 0000000..5f87588 --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json @@ -0,0 +1,15422 @@ +[ + { + "text": "H", + "encodingTable": { + "H": "1" + }, + "compressed": [ + 1 + ] + }, + { + "text": "Hello, World!", + "encodingTable": { + " ": "1010", + "!": "1011", + "r": "1100", + "d": "1101", + "e": "1110", + "W": "1111", + "H": "000", + ",": "001", + "l": "01", + "o": "100" + }, + "compressed": [ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1 + ] + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "compressed": [ + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ] + } +] diff --git a/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json b/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json new file mode 100644 index 0000000..a81453a --- /dev/null +++ b/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json @@ -0,0 +1,17 @@ +[ + { + "text": "" + }, + { + "text": "H" + }, + { + "text": "Hello, World!" + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh." + }, + { + "text": "Habs bi dies en satz. Oha was gefallt woruber erzahlt das stellte steigst tat glatten. Ige der kraftiger schneider plaudernd vom schonsten. Es du kenne vater stuck. Namlich abwarts gut mundart gab tur nur. Viele du immer szene leise kaute so.\n\nGar meisterin ihn arbeitete uhr ernsthaft. Im bewirtung da gestorben du zerfasert verodeten. Frohlich ist schuftet hinabsah begierig gar dus ihr. Stimmts weg gedacht glatten zum weibern ort ist. Hande sehet kennt te da lauft. Ichs in welt pa eile hing. Ei betrubte da wo geworden launisch ehrbaren madchens.\n\nZu ku auskleiden aufzulosen dazwischen. Lockere ich grausam mundart hochmut ein fenster. Du aufraumen lieblinge geblendet vergesset zu. Mit bettstatt gib schneider hemdarmel unterwegs war. Sog klein das sagen kalte leise vom zwirn licht. Hellen verlie uhr kommen jungen bis freute eck schade gut. Samstag konnten gefreut nun zuliebe vor lichten.\n\nBat ist landsleute hin nachmittag vorpfeifen. Pa es klopfte an flecken wu tadelte. Darauf dus neckte hin als gebaut lag. Kindliche weiterhin mannsbild ob zu windstill. Herr gast sei gut ists. Hufschmied bat ehe wei scherzwort drechslers grundstuck wohlgefuhl man aufgespart. Gehe se luke ruth weil en ei wege. Schen kennt nobel sie gut wie und schau dafur.\n\nSo zaunpfahle mi neidgefuhl em vertreiben wo gesprachig angenommen. Du em paar muhe in so doch. In es frauen te kunste kurios zu. Ist denen leise weich nacht aller eia man steht ich. Losen es ewige zu nicht leben. Hinabsah leichter tadellos mehrmals im ziemlich la em wo.\n\nSa gelernte he am uberging verwohnt. Liebhaben mudigkeit gestrigen nie kam wie tanzmusik ausdenken. An wo du gerbers gelehnt so schritt. Musset mochte du gesund es la sprach seinen. Ubel all tat gelt eine sie tor lied. Verschwand hoffnungen todesfalle er ri an da nettigkeit. Geworden in schonste familien launigen nirgends mi.\n\nIhr grasgarten aus gab ich vorpfeifen nettigkeit bodenlosen. Es ziegen jawohl freude bi fraget bugeln. Em tage te bett arme. Er heran ab so hinab damit rasch. Luften verlie zopfen dir nur. Warf geh alle beim frau den. So heiraten zu konntest fraulein schweren la. Dem beneidest tanzmusik ehe ausdenken gegriffen kraftiger arbeitete gro. Hufschmied verbergend em am sa aufzulosen. Redete luftig klaren fur nur strich stimme ers nur.\n\nVor zog was will ehre paar des. Meinung gelernt scheint flo gefreut manchen das. Es lehrlingen da in nachtessen geschwatzt erhaltenen sonderling schuchtern. Nirgends mi gespielt zugvogel weiblein er em. Ja werkstatte an bescheiden hufschmied neidgefuhl. Ei handwerke en ernstlich kammertur barbieren.\n\nPa wohnstube er kindliche ri schonheit da. Befangenen ihr fluchtigen die lag dachkammer mit. Funfe an schlo enden ja dabei zu es licht. Nichtstun nachgehen im wo lohgruben. Vom ausdenken ist hei filzhutes leuchtete hochstens. Um gern hing so laut da hast.\n\nGesehen konnten in wu dunklem schaute. Einige je wo en in groben besann spater verlor. Schuchtern geheiratet in verrichtet pa bodenlosen betrachtet se am vorpfeifen. Kleine grunde ja da luften werden reihen. Ahren alten enden wo sunde in immer du. Wahrend wie ein nur bereits gewogen niemand man. Froh du voll hing im kerl in euch funf zu. Gebogene ort brauchte uberlegt gut." + } +] diff --git a/H12/src/main/java/h12/Main.java b/H12/src/main/java/h12/Main.java new file mode 100644 index 0000000..2479ee8 --- /dev/null +++ b/H12/src/main/java/h12/Main.java @@ -0,0 +1,16 @@ +package h12; + +/** + * Main entry point in executing the program. + */ +public class Main { + + /** + * Main entry point in executing the program. + * + * @param args program arguments, currently ignored + */ + public static void main(String[] args) { + System.out.println("Hello World!"); + } +} diff --git a/H12/src/main/java/h12/io/BitInputStream.java b/H12/src/main/java/h12/io/BitInputStream.java new file mode 100644 index 0000000..a41cc2a --- /dev/null +++ b/H12/src/main/java/h12/io/BitInputStream.java @@ -0,0 +1,20 @@ +package h12.io; + +import java.io.IOException; +import java.io.InputStream; + +/** + * An input stream which allows additionally reading bits. + * + * @author Per Göttlicher, Nhan Huynh + */ +public abstract class BitInputStream extends InputStream { + + /** + * Reads a single bit from the input stream. + * + * @return the bit read from the input stream or -1 if the end of the stream has been reached + * @throws IOException if an I/O error occurs + */ + public abstract int readBit() throws IOException; +} diff --git a/H12/src/main/java/h12/io/BitOutStream.java b/H12/src/main/java/h12/io/BitOutStream.java new file mode 100644 index 0000000..701836d --- /dev/null +++ b/H12/src/main/java/h12/io/BitOutStream.java @@ -0,0 +1,23 @@ +package h12.io; + +import h12.lang.MyBit; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * An input stream which allows additionally reading bits. + * + * @author Per Göttlicher, Nhan Huynh + */ +public abstract class BitOutStream extends OutputStream { + + /** + * Writes a single bit to the output stream. + * + * @param bit the bit to write + * + * @throws IOException if an I/O error occurs + */ + public abstract void writeBit(MyBit bit) throws IOException; +} diff --git a/H12/src/main/java/h12/io/BufferedBitInputStream.java b/H12/src/main/java/h12/io/BufferedBitInputStream.java new file mode 100644 index 0000000..fba2dc6 --- /dev/null +++ b/H12/src/main/java/h12/io/BufferedBitInputStream.java @@ -0,0 +1,112 @@ +package h12.io; + +import h12.lang.MyByte; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.io.IOException; +import java.io.InputStream; + +/** + * An input stream that reads bits from an underlying input stream. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class BufferedBitInputStream extends BitInputStream { + + /** + * The value returned when the stream has reached the end or the beginning of the stream. + */ + private static final int INVALID = -1; + + /** + * The underlying input stream. + */ + @DoNotTouch + private final InputStream underlying; + + /** + * The buffer used for reading bits. + */ + private @Nullable MyByte buffer; + + /** + * The position of the next bit to read in the buffer. + */ + private int position = INVALID; + + /** + * Constructs a new bit input stream with the specified underlying input stream. + * + * @param underlying the underlying input stream + */ + @DoNotTouch + public BufferedBitInputStream(InputStream underlying) { + this.underlying = underlying; + } + + /** + * Fetches the next byte from the underlying input stream to the buffer. + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.1.1") + protected void fetch() throws IOException { + // TODO H12.1.1 + org.tudalgo.algoutils.student.Student.crash("H12.1.1 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.1.1") + @Override + public int readBit() throws IOException { + // TODO H12.1.1 + return org.tudalgo.algoutils.student.Student.crash("H12.1.1 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.1.1") + @Override + public int read() throws IOException { + // TODO H12.1.1 + return org.tudalgo.algoutils.student.Student.crash("H12.1.1 - Remove if implemented"); + } + + /** + * Reads up to {@code len} bytes of data from the input stream into an array of bytes. + * + * @param b the buffer into which the data is read. + * @param off the start offset in array {@code b} + * at which the data is written. + * @param len the maximum number of bytes to read. + * + * @return the total number of bytes read into the buffer, or -1 if there is no more data because the end of the + * stream has been reached. + * @throws IOException if an I/O error occurs. + */ + @DoNotTouch + public int read(byte @NotNull [] b, int off, int len) throws IOException { + int read = 0; + for (int i = 0; i < len; i++) { + int value = read(); + // In case we reached the end of the stream, and the buffer is empty, return -1 + if (value == INVALID && i == 0) { + return -1; + } + // In case we reached the end of the stream, return the number of values read so far + if (value == INVALID) { + return read; + } + b[off + i] = (byte) value; + read++; + } + return read; + } + + @DoNotTouch + @Override + public void close() throws IOException { + underlying.close(); + } +} diff --git a/H12/src/main/java/h12/io/BufferedBitOutputStream.java b/H12/src/main/java/h12/io/BufferedBitOutputStream.java new file mode 100644 index 0000000..53231f8 --- /dev/null +++ b/H12/src/main/java/h12/io/BufferedBitOutputStream.java @@ -0,0 +1,83 @@ +package h12.io; + +import h12.lang.MyBit; +import h12.lang.MyByte; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * An output stream that writes bits to an underlying output stream. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class BufferedBitOutputStream extends BitOutStream { + + /** + * The underlying output stream. + */ + @DoNotTouch + private final OutputStream underlying; + + /** + * The buffer used for writing bits. + */ + private MyByte buffer = new MyByte(); + + /** + * The position of the next bit to write in the buffer. + */ + private int position = MyByte.NUMBER_OF_BITS - 1; + + /** + * Constructs a new bit output stream with the specified underlying output stream. + * + * @param underlying the underlying output stream + */ + @DoNotTouch + public BufferedBitOutputStream(OutputStream underlying) { + this.underlying = underlying; + } + + /** + * Flushes the buffer if it is not empty to write the remaining bits to the underlying output stream. + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.1.2") + protected void flushBuffer() throws IOException { + // TODO H12.1.2 + org.tudalgo.algoutils.student.Student.crash("H12.1.2 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.1.2") + @Override + public void writeBit(MyBit bit) throws IOException { + // TODO H12.1.2 + org.tudalgo.algoutils.student.Student.crash("H12.1.2 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.1.2") + @Override + public void write(int b) throws IOException { + // TODO H12.1.2 + org.tudalgo.algoutils.student.Student.crash("H12.1.2 - Remove if implemented"); + } + + @DoNotTouch + @Override + public void flush() throws IOException { + flushBuffer(); + underlying.flush(); + } + + @DoNotTouch + @Override + public void close() throws IOException { + flush(); + underlying.close(); + } +} diff --git a/H12/src/main/java/h12/io/compress/Compressor.java b/H12/src/main/java/h12/io/compress/Compressor.java new file mode 100644 index 0000000..4185c6e --- /dev/null +++ b/H12/src/main/java/h12/io/compress/Compressor.java @@ -0,0 +1,22 @@ +package h12.io.compress; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.io.IOException; + +/** + * Represents a compressor that can compress a file. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public interface Compressor extends AutoCloseable { + + /** + * Compresses the file. + * + * @throws IOException if an I/O error occurs + */ + @DoNotTouch + void compress() throws IOException; +} diff --git a/H12/src/main/java/h12/io/compress/Decompressor.java b/H12/src/main/java/h12/io/compress/Decompressor.java new file mode 100644 index 0000000..e79eacd --- /dev/null +++ b/H12/src/main/java/h12/io/compress/Decompressor.java @@ -0,0 +1,22 @@ +package h12.io.compress; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.io.IOException; + +/** + * Represents a decompressor that can decompress a file. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public interface Decompressor extends AutoCloseable { + + /** + * Decompresses the file. + * + * @throws IOException if an I/O error occurs + */ + @DoNotTouch + void decompress() throws IOException; +} diff --git a/H12/src/main/java/h12/io/compress/EncodingTable.java b/H12/src/main/java/h12/io/compress/EncodingTable.java new file mode 100644 index 0000000..a791495 --- /dev/null +++ b/H12/src/main/java/h12/io/compress/EncodingTable.java @@ -0,0 +1,71 @@ +package h12.io.compress; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.util.NoSuchElementException; + +/** + * A table that maps characters to their codes. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public interface EncodingTable { + + /** + * Returns whether the encoding table contains the given character. + * + * @param character the character to check + * + * @return true if the encoding table contains the character, false otherwise + */ + boolean containsCharacter(Character character); + + /** + * Returns whether the encoding table contains the given code. + * + * @param code the code to check + * + * @return true if the encoding table contains the code, false otherwise + */ + boolean containsCode(String code); + + /** + * Returns whether the encoding table contains the given code. + * + * @param iterable the Huffman code to check + * + * @return {@code true} if the encoding table contains the code, {@code false} otherwise + */ + boolean containsCode(Iterable iterable); + + /** + * Returns the Huffman code of the given character. + * + * @param character the character to get the code for + * + * @return the Huffman code of the character + * @throws NoSuchElementException if the character is not in the encoding table + */ + String getCode(Character character); + + /** + * Returns the character of the given Huffman code. + * + * @param code the Huffman code to get the character for + * + * @return the character of the code + * @throws NoSuchElementException if the code is not in the encoding table + */ + Character getCharacter(String code); + + /** + * Returns the character of the given Huffman code. + * + * @param iterable the Huffman code to get the character for + * + * @return the character of the code + * @throws NoSuchElementException if the code is not in the encoding table + */ + Character getCharacter(Iterable iterable); +} diff --git a/H12/src/main/java/h12/io/compress/huffman/HuffmanCoding.java b/H12/src/main/java/h12/io/compress/huffman/HuffmanCoding.java new file mode 100644 index 0000000..ddc827d --- /dev/null +++ b/H12/src/main/java/h12/io/compress/huffman/HuffmanCoding.java @@ -0,0 +1,108 @@ +package h12.io.compress.huffman; + +import h12.io.compress.EncodingTable; +import h12.util.TreeNode; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.function.BiFunction; + +/** + * The Huffman coding algorithm to compress and decompress data. + * + *

It is used to compress data by encoding characters with variable-length codes based on their frequency. + * + *

The Huffman tree is built from the frequency table of characters and used to build the encoding table. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public final class HuffmanCoding { + + /** + * Returns the frequency table of characters in the given text. + * + * @param text the text to build the frequency table from + * + * @return the frequency table of characters in the text + */ + @StudentImplementationRequired("H12.3.1") + public Map buildFrequencyTable(String text) { + // TODO H12.3.1 + return org.tudalgo.algoutils.student.Student.crash("H12.3.1 - Remove if implemented"); + } + + /** + * Removes and returns the minimum element from the given collection using the given comparator. + * + * @param elements the collection to remove the minimum element from + * @param cmp the comparator to compare elements + * @param the type of elements in the collection + * + * @return the minimum element + */ + @StudentImplementationRequired("H12.3.2") + T removeMin(Collection elements, Comparator cmp) { + // TODO H12.3.2 + return org.tudalgo.algoutils.student.Student.crash("H12.3.2 - Remove if implemented"); + } + + /** + * Builds indirectly a tree from the given frequency table of characters using the given functions and comparator. + * + * @param frequency the frequency table of characters + * @param f maps a character and its frequency an element representing both values + * @param g combines two elements into a new element + * @param cmp the comparator to compare elements and remove the minimum element + * @param the type of elements to build the tree from + * + * @return the Huffman tree built from the frequency table + */ + @StudentImplementationRequired("H12.3.2") + T build( + Map frequency, + BiFunction f, + BiFunction g, + Comparator cmp + ) { + // TODO H12.3.2 + return org.tudalgo.algoutils.student.Student.crash("H12.3.2 - Remove if implemented"); + } + + /** + * Builds the Huffman tree from the given frequency table of characters. + * + * @param frequency the frequency table of characters + * + * @return the Huffman tree built from the frequency table + */ + @DoNotTouch + private TreeNode buildTree(Map frequency) { + return build( + frequency, + HuffmanTreeNode::new, + (left, right) -> { + HuffmanTreeNode parent = new HuffmanTreeNode(left, right, left.getFrequency() + right.getFrequency()); + left.setParent(parent); + right.setParent(parent); + return parent; + }, + Comparator.comparingInt(HuffmanTreeNode::getFrequency) + ); + } + + /** + * Returns the encoding table of characters in the given text. + * + * @param frequencyTable the frequency table of characters + * + * @return the encoding table of characters in the text + */ + @DoNotTouch + public EncodingTable buildEncodingTable(Map frequencyTable) { + return new HuffmanEncodingTable(buildTree(frequencyTable)); + } +} diff --git a/H12/src/main/java/h12/io/compress/huffman/HuffmanCodingCompressor.java b/H12/src/main/java/h12/io/compress/huffman/HuffmanCodingCompressor.java new file mode 100644 index 0000000..ef9ef09 --- /dev/null +++ b/H12/src/main/java/h12/io/compress/huffman/HuffmanCodingCompressor.java @@ -0,0 +1,191 @@ +package h12.io.compress.huffman; + +import h12.io.BitOutStream; +import h12.io.BufferedBitOutputStream; +import h12.io.compress.Compressor; +import h12.io.compress.EncodingTable; +import h12.lang.MyBit; +import h12.lang.MyBytes; +import h12.util.TreeNode; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + +/** + * A compressor that uses the Huffman coding algorithm to compress data. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class HuffmanCodingCompressor implements Compressor { + + /** + * The input stream to read the text from. + */ + @DoNotTouch + private final BufferedReader in; + + /** + * The output stream to write the compressed data to. + */ + @DoNotTouch + private final BitOutStream out; + + /** + * Creates a new compressor with the given input to compress and output to write to. + * + * @param in the input stream to read the text from + * @param out the output stream to write the compressed data to + */ + @DoNotTouch + public HuffmanCodingCompressor(InputStream in, OutputStream out) { + this.in = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); + this.out = out instanceof BitOutStream bitOut ? bitOut : new BufferedBitOutputStream(out); + } + + /** + * Reads the content to compress from the input stream. + * + * @return the text read from the input stream + */ + @StudentImplementationRequired("H12.4.1") + protected String getText() throws IOException { + // TODO H12.4.1 + return org.tudalgo.algoutils.student.Student.crash("H12.4.1 - Remove if implemented"); + } + + /** + * Computes the number of fill bits needed to fill the first byte of the compressed data. + * + * @param text the text to compress + * @param encodingTable the encoding table to use + * + * @return the number of fill bits needed + */ + @DoNotTouch + protected int computeFillBits(String text, EncodingTable encodingTable) { + HuffmanEncodingTable table = (HuffmanEncodingTable) encodingTable; + return MyBytes.computeMissingBits(computeHeaderSize(table) + computeTextSize(text, table)); + } + + /** + * Computes the size of the header in bits needed to encode the Huffman tree. + * + * @param encodingTable the encoding table to use + * + * @return the size of the header in bits + */ + @DoNotTouch + private int computeHeaderSize(EncodingTable encodingTable) { + return computeHeaderSize(((HuffmanEncodingTable) encodingTable).getRoot()); + } + + /** + * Computes the size of the header in bits needed to encode the Huffman tree. + * + * @param node the node to compute the size from + * + * @return the size of the header in bits + */ + @SuppressWarnings("ConstantConditions") + private int computeHeaderSize(TreeNode node) { + if (node.isLeaf()) { + return 1 + 32; + } else { + return 1 + computeHeaderSize(node.getLeft()) + computeHeaderSize(node.getRight()); + } + } + + /** + * Computes the size of the text in bits needed to encode the text. + * + * @param text the text to compress + * @param encodingTable the encoding table to use + * + * @return the size of the text in bits + */ + @StudentImplementationRequired("H12.4.1") + protected int computeTextSize(String text, EncodingTable encodingTable) { + // TODO H12.4.1 + return org.tudalgo.algoutils.student.Student.crash("H12.4.1 - Remove if implemented"); + } + + /** + * Fills the first byte with the given number of bits. + * + * @param count the number of bits to fill + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.4.1") + protected void fillBits(int count) throws IOException { + // TODO H12.4.1 + org.tudalgo.algoutils.student.Student.crash("H12.4.1 - Remove if implemented"); + } + + /** + * Encodes the header of the compressed data using the given encoding table. + * + * @param encodingTable the encoding table to use + * + * @throws IOException if an I/O error occurs + */ + @DoNotTouch + private void encodeHeader(EncodingTable encodingTable) throws IOException { + encodeHeader(((HuffmanEncodingTable) encodingTable).getRoot()); + } + + /** + * Encodes the header of the compressed data using the given node until a leaf node is reached. + * + * @param node the node to encode + * + * @throws IOException if an I/O error occurs + */ + @DoNotTouch + @SuppressWarnings("ConstantConditions") + private void encodeHeader(TreeNode node) throws IOException { + if (node.isLeaf()) { + out.writeBit(MyBit.ONE); + out.write(MyBytes.toBytes(node.getValue())); + } else { + out.writeBit(MyBit.ZERO); + encodeHeader(node.getLeft()); + encodeHeader(node.getRight()); + } + } + + /** + * Encodes the content of the compressed data using the given text and encoding table. + * + * @param text the text to compress + * @param encodingTable the encoding table to use + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.4.1") + protected void encodeText(String text, EncodingTable encodingTable) throws IOException { + // TODO H12.4.1 + org.tudalgo.algoutils.student.Student.crash("H12.4.1 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.4.1") + @Override + public void compress() throws IOException { + // TODO H12.4.1 + org.tudalgo.algoutils.student.Student.crash("H12.4.1 - Remove if implemented"); + } + + @DoNotTouch + @Override + public void close() throws Exception { + in.close(); + out.close(); + } +} diff --git a/H12/src/main/java/h12/io/compress/huffman/HuffmanCodingDecompressor.java b/H12/src/main/java/h12/io/compress/huffman/HuffmanCodingDecompressor.java new file mode 100644 index 0000000..9b9a651 --- /dev/null +++ b/H12/src/main/java/h12/io/compress/huffman/HuffmanCodingDecompressor.java @@ -0,0 +1,141 @@ +package h12.io.compress.huffman; + +import h12.io.BitInputStream; +import h12.io.BufferedBitInputStream; +import h12.io.compress.Decompressor; +import h12.io.compress.EncodingTable; +import h12.lang.MyBytes; +import h12.util.TreeNode; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; + +/** + * A decompressor that uses the Huffman coding algorithm to decompress data. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class HuffmanCodingDecompressor implements Decompressor { + + /** + * The input stream to read the compressed data from. + */ + @DoNotTouch + private final BitInputStream in; + + /** + * The output writer to write the decompressed data to. + */ + @DoNotTouch + private final Writer out; + + /** + * Creates a new decompressor with the given input to decompress and output to write to. + * + * @param in the input stream to read the compressed data from + * @param out the output stream to write the decompressed data to + */ + @DoNotTouch + public HuffmanCodingDecompressor(InputStream in, OutputStream out) { + this.in = in instanceof BitInputStream bitIn ? bitIn : new BufferedBitInputStream(in); + this.out = new OutputStreamWriter(out, StandardCharsets.UTF_8); + } + + /** + * Skips the filled bits of the first byte. + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.4.2") + protected void skipBits() throws IOException { + // TODO H12.4.2 + org.tudalgo.algoutils.student.Student.crash("H12.4.2 - Remove if implemented"); + } + + /** + * Decodes the header of the compressed data to build the encoding table. + * + * @return the encoding table built from the header + * @throws IOException if an I/O error occurs + */ + @DoNotTouch + private EncodingTable decodeHeader() throws IOException { + return new HuffmanEncodingTable(decodeTree()); + } + + /** + * Decodes the Huffman tree recursively. + * + * @return the root of the Huffman tree decoded + * @throws IOException if an I/O error occurs + */ + @DoNotTouch + @SuppressWarnings("ResultOfMethodCallIgnored") + private TreeNode decodeTree() throws IOException { + if (in.readBit() == 1) { + byte[] bytes = new byte[4]; + in.read(bytes); + return new TreeNode<>(MyBytes.toChar(bytes)); + } + TreeNode left = decodeTree(); + TreeNode right = decodeTree(); + TreeNode parent = new TreeNode<>(left, right); + left.setParent(parent); + right.setParent(parent); + return parent; + } + + /** + * Decodes a character from the compressed data. + * + * @param startBit the first bit of the character + * @param encodingTable the encoding table to use + * + * @return the decoded character from the compressed data + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.4.2") + char decodeCharacter(int startBit, EncodingTable encodingTable) throws IOException { + // TODO H12.4.2 + return org.tudalgo.algoutils.student.Student.crash("H12.4.2 - Remove if implemented"); + } + + /** + * Decodes the content of the compressed data using the given encoding table. + * + * @param encodingTable the encoding table to use + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.4.2") + void decodeText(EncodingTable encodingTable) throws IOException { + // TODO H12.4.2 + org.tudalgo.algoutils.student.Student.crash("H12.4.2 - Remove if implemented"); + } + + /** + * Decompresses the data using the Huffman coding algorithm. + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.4.2") + @Override + public void decompress() throws IOException { + // TODO H12.4.2 + org.tudalgo.algoutils.student.Student.crash("H12.4.2 - Remove if implemented"); + } + + @DoNotTouch + @Override + public void close() throws Exception { + in.close(); + out.close(); + } +} diff --git a/H12/src/main/java/h12/io/compress/huffman/HuffmanEncodingTable.java b/H12/src/main/java/h12/io/compress/huffman/HuffmanEncodingTable.java new file mode 100644 index 0000000..44618d8 --- /dev/null +++ b/H12/src/main/java/h12/io/compress/huffman/HuffmanEncodingTable.java @@ -0,0 +1,223 @@ +package h12.io.compress.huffman; + +import h12.io.compress.EncodingTable; +import h12.util.TreeNode; +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.util.HashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +/** + * A table that maps characters to their Huffman codes. + * + *

It is used to encode and decode data using the Huffman coding algorithm. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +class HuffmanEncodingTable implements EncodingTable { + + /** + * The root of the Huffman tree. + */ + @DoNotTouch + protected final TreeNode root; + + /** + * The map that stores the encodings of characters. + */ + @DoNotTouch + protected @Nullable Map encodings = null; + + /** + * Creates a new encoding table with the given root of the Huffman tree to build the table from. + * + * @param root the root of the Huffman tree + */ + @DoNotTouch + public HuffmanEncodingTable(TreeNode root) { + this.root = root; + } + + /** + * Returns the root of the Huffman tree. + * + * @return the root of the Huffman tree + */ + @DoNotTouch + public TreeNode getRoot() { + return root; + } + + /** + * Builds the encoding table from the Huffman tree. + */ + @DoNotTouch + private void buildEncodingTable() { + encodings = new HashMap<>(); + buildEncodingTable(root, ""); + if (encodings.size() == 1) { + encodings.put(root.getValue(), "1"); + } + } + + /** + * Builds the encoding table recursively from the given node. + * + * @param root the current node + * @param builder the current encoding built so far + */ + @DoNotTouch + private void buildEncodingTable(TreeNode root, String builder) { + if (root.isLeaf()) { + assert root.getValue() != null; + assert encodings != null; + encodings.put(root.getValue(), builder); + } else { + assert root.getLeft() != null; + assert root.getRight() != null; + buildEncodingTable(root.getLeft(), builder + "0"); + buildEncodingTable(root.getRight(), builder + "1"); + } + } + + /** + * Returns whether the encoding table contains the given character. + * + * @param character the character to check + * + * @return true if the encoding table contains the character, false otherwise + */ + @DoNotTouch + @Override + public boolean containsCharacter(Character character) { + if (encodings == null) { + buildEncodingTable(); + } + return encodings != null && encodings.containsKey(character); + } + + /** + * Returns whether the encoding table contains the given code. + * + * @param code the code to check + * + * @return true if the encoding table contains the code, false otherwise + */ + @DoNotTouch + @Override + public boolean containsCode(String code) { + try { + getCharacter(code); + return true; + } catch (NoSuchElementException e) { + return false; + } + } + + /** + * Returns whether the encoding table contains the given code. + * + * @param iterable the Huffman code to check + * + * @return {@code true} if the encoding table contains the code, {@code false} otherwise + */ + @DoNotTouch + @Override + public boolean containsCode(Iterable iterable) { + return containsCode(StreamSupport.stream(iterable.spliterator(), false) + .map(String::valueOf) + .collect(Collectors.joining())); + } + + /** + * Returns the Huffman code of the given character. + * + * @param character the character to get the code for + * + * @return the Huffman code of the character + * @throws NoSuchElementException if the character is not in the encoding table + */ + @DoNotTouch + @Override + public String getCode(Character character) { + if (encodings == null) { + buildEncodingTable(); + } + if (!encodings.containsKey(character)) { + throw new NoSuchElementException("'" + character + "'"); + } + return encodings.get(character); + } + + /** + * Returns the character of the given Huffman code. + * + * @param code the Huffman code to get the character for + * + * @return the character of the code + * @throws NoSuchElementException if the code is not in the encoding table + */ + @DoNotTouch + @Override + public Character getCharacter(String code) { + TreeNode current = root; + if (current.isLeaf()) { + return current.getValue(); + } + for (char c : code.toCharArray()) { + if (c == '0') { + current = current.getLeft(); + } else { + current = current.getRight(); + } + assert current != null; + if (current.isLeaf()) { + return current.getValue(); + } + } + throw new NoSuchElementException(code); + } + + /** + * Returns the character of the given Huffman code. + * + * @param iterable the Huffman code to get the character for + * + * @return the character of the code + * @throws NoSuchElementException if the code is not in the encoding table + */ + @DoNotTouch + @Override + public Character getCharacter(Iterable iterable) { + return getCharacter(StreamSupport.stream(iterable.spliterator(), false) + .map(String::valueOf) + .collect(Collectors.joining())); + } + + @DoNotTouch + @Override + public boolean equals(Object o) { + return this == o || o instanceof HuffmanEncodingTable that && Objects.equals(root, that.root); + } + + @DoNotTouch + @Override + public int hashCode() { + return Objects.hashCode(root); + } + + @DoNotTouch + @Override + public String toString() { + if (encodings == null) { + buildEncodingTable(); + } + return encodings.toString(); + } +} diff --git a/H12/src/main/java/h12/io/compress/huffman/HuffmanTreeNode.java b/H12/src/main/java/h12/io/compress/huffman/HuffmanTreeNode.java new file mode 100644 index 0000000..c16fc5d --- /dev/null +++ b/H12/src/main/java/h12/io/compress/huffman/HuffmanTreeNode.java @@ -0,0 +1,77 @@ +package h12.io.compress.huffman; + +import h12.util.TreeNode; +import org.jetbrains.annotations.NotNull; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.util.Objects; + +/** + * A node in a Huffman tree which can be either a leaf node with a character value or an internal node with a frequency. + * The frequency is the sum of the frequencies of its children and is used to build the Huffman tree. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public final class HuffmanTreeNode extends TreeNode implements Comparable { + + /** + * The frequency of this node. + */ + @DoNotTouch + private final int frequency; + + /** + * Creates a new internal node with the given left and right children and frequency. + * + * @param left the left child + * @param right the right child + * @param frequency the frequency of this node + */ + @DoNotTouch + public HuffmanTreeNode(TreeNode left, TreeNode right, int frequency) { + super(left, right, null); + this.frequency = frequency; + } + + /** + * Creates a new leaf node with the given value and frequency. + * + * @param value the value of this node + * @param frequency the frequency of this node + */ + @DoNotTouch + public HuffmanTreeNode(Character value, int frequency) { + super(value); + this.frequency = frequency; + } + + /** + * Returns the frequency of this node. + * + * @return the frequency of this node + */ + @DoNotTouch + public int getFrequency() { + return frequency; + } + + @DoNotTouch + @Override + public int compareTo(@NotNull HuffmanTreeNode o) { + return Integer.compare(frequency, o.frequency); + } + + @DoNotTouch + @Override + public boolean equals(Object o) { + return this == o || o instanceof HuffmanTreeNode that && frequency == that.frequency; + } + + @DoNotTouch + @Override + public int hashCode() { + return Objects.hashCode(frequency); + } +} + diff --git a/H12/src/main/java/h12/io/compress/rle/BitRunningLengthCompressor.java b/H12/src/main/java/h12/io/compress/rle/BitRunningLengthCompressor.java new file mode 100644 index 0000000..34c445d --- /dev/null +++ b/H12/src/main/java/h12/io/compress/rle/BitRunningLengthCompressor.java @@ -0,0 +1,87 @@ +package h12.io.compress.rle; + +import h12.io.BitInputStream; +import h12.io.BitOutStream; +import h12.io.BufferedBitInputStream; +import h12.io.BufferedBitOutputStream; +import h12.io.compress.Compressor; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A simple compressor that uses the running length encoding algorithm to compress data. + * + *

E.g. the input 111111111111111111110000111111 would be compressed to 100010000000010010000110 to represent 20 + * ones, 4 zeros, and 6 ones. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class BitRunningLengthCompressor implements Compressor { + + /** + * The maximum count that can be stored in a byte without the bit at position 7 (X111 1111 = 127). + */ + public static final int MAX_COUNT = (int) Math.pow(2, 7) - 1; + + /** + * The input stream to read from. + */ + @DoNotTouch + private final BitInputStream in; + + /** + * The output stream to write to. + */ + @DoNotTouch + private final BitOutStream out; + + /** + * The last read bit. + */ + private int lastRead = -1; + + /** + * Creates a new compressor with the given input to compress and output to write to. + * + * @param in the input stream to read from + * @param out the output stream to write to + */ + @DoNotTouch + public BitRunningLengthCompressor(InputStream in, OutputStream out) { + this.in = in instanceof BitInputStream bitIn ? bitIn : new BufferedBitInputStream(in); + this.out = out instanceof BitOutStream bitOut ? bitOut : new BufferedBitOutputStream(out); + } + + /** + * Returns the number of bits that are the same as the given bit. + * + * @param bit the bit to count + * + * @return the number of bits that are the same as the given bit + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.2.1") + protected int getBitCount(int bit) throws IOException { + // TODO H12.2.1 + return org.tudalgo.algoutils.student.Student.crash("H12.2.1 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.2.1") + @Override + public void compress() throws IOException { + // TODO H12.2.1 + org.tudalgo.algoutils.student.Student.crash("H12.2.1 - Remove if implemented"); + } + + @DoNotTouch + @Override + public void close() throws Exception { + in.close(); + out.close(); + } +} diff --git a/H12/src/main/java/h12/io/compress/rle/BitRunningLengthDecompressor.java b/H12/src/main/java/h12/io/compress/rle/BitRunningLengthDecompressor.java new file mode 100644 index 0000000..223211d --- /dev/null +++ b/H12/src/main/java/h12/io/compress/rle/BitRunningLengthDecompressor.java @@ -0,0 +1,78 @@ +package h12.io.compress.rle; + +import h12.io.BitInputStream; +import h12.io.BitOutStream; +import h12.io.BufferedBitInputStream; +import h12.io.BufferedBitOutputStream; +import h12.io.compress.Decompressor; +import h12.lang.MyBit; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A simple decompressor that uses the running length encoding algorithm to decompress data. + * + *

E.g. the input 100010000000010010000110 would be decompressed to 111111111111111111110000111111 to represent + * 20 ones, 4 zeros, and 6 ones. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class BitRunningLengthDecompressor implements Decompressor { + + /** + * The input stream to decompress from. + */ + @DoNotTouch + private final BitInputStream in; + + /** + * The output stream to write to. + */ + @DoNotTouch + private final BitOutStream out; + + /** + * Creates a new decompressor with the given input to decompress and output to write to. + * + * @param in the input stream to decompress from + * @param out the output stream to write to + */ + @DoNotTouch + public BitRunningLengthDecompressor(InputStream in, OutputStream out) { + this.in = in instanceof BitInputStream bitIn ? bitIn : new BufferedBitInputStream(in); + this.out = out instanceof BitOutStream bitOut ? bitOut : new BufferedBitOutputStream(out); + } + + /** + * Writes the given bit count times to the output stream. + * + * @param count the number of bits to write + * @param bit the bit to write + * + * @throws IOException if an I/O error occurs + */ + @StudentImplementationRequired("H12.2.2") + protected void writeBit(int count, MyBit bit) throws IOException { + // TODO H12.2.2 + org.tudalgo.algoutils.student.Student.crash("H12.2.2 - Remove if implemented"); + } + + @StudentImplementationRequired("H12.2.2") + @Override + public void decompress() throws IOException { + // TODO H12.2.2 + org.tudalgo.algoutils.student.Student.crash("H12.2.2 - Remove if implemented"); + } + + @DoNotTouch + @Override + public void close() throws Exception { + in.close(); + out.close(); + } +} diff --git a/H12/src/main/java/h12/lang/MyBit.java b/H12/src/main/java/h12/lang/MyBit.java new file mode 100644 index 0000000..7ad75e8 --- /dev/null +++ b/H12/src/main/java/h12/lang/MyBit.java @@ -0,0 +1,95 @@ +package h12.lang; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.util.Objects; + +/** + * Represents a bit with the value of 0 or 1. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public final class MyBit { + + /** + * The bit with the value of 0. + */ + @DoNotTouch + public static final MyBit ZERO = new MyBit(0); + + /** + * The bit with the value of 1. + */ + @DoNotTouch + public static final MyBit ONE = new MyBit(1); + + /** + * The value of the bit. + */ + @DoNotTouch + private final int value; + + /** + * Constructs a new bit with the specified value. + * + * @param value the value of the bit + */ + @DoNotTouch + private MyBit(int value) { + this.value = value; + } + + /** + * Returns the bit with the specified value. + * + * @param value the value of the bit + * + * @return the bit with the specified value + * @throws IllegalArgumentException if the value is not 0 or 1 + */ + @DoNotTouch + public static MyBit fromInt(int value) { + if (value != 0 && value != 1) { + throw new IllegalArgumentException("Bit must be 0 or 1: %d".formatted(value)); + } + return value == ONE.intValue() ? ONE : ZERO; + } + + /** + * Returns the value of the bit as an integer. + * + * @return the value of the bit as an integer + */ + @DoNotTouch + public int intValue() { + return value; + } + + /** + * Flips this bit. + * + * @return the flipped bit + */ + public MyBit flip() { + return value == 0 ? ONE : ZERO; + } + + @DoNotTouch + @Override + public boolean equals(Object o) { + return this == o || o instanceof MyBit bit && value == bit.value; + } + + @DoNotTouch + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + @DoNotTouch + @Override + public String toString() { + return "Bit{value=%s}".formatted(value); + } +} diff --git a/H12/src/main/java/h12/lang/MyByte.java b/H12/src/main/java/h12/lang/MyByte.java new file mode 100644 index 0000000..0f7ced7 --- /dev/null +++ b/H12/src/main/java/h12/lang/MyByte.java @@ -0,0 +1,237 @@ +package h12.lang; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Represents a byte with eight bits. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public final class MyByte { + + /** + * The number of bits in a byte. + */ + @DoNotTouch + public static final int NUMBER_OF_BITS = 8; + + /** + * The minimum position of a bit. + */ + public static final int MIN_POSITION = 0; + + /** + * The maximum position of a bit. + */ + public static final int MAX_POSITION = NUMBER_OF_BITS - 1; + + /** + * The maximum value of a byte. + */ + @DoNotTouch + public static final int MAX_VALUE = 255; + + /** + * The minimum value of a byte. + */ + @DoNotTouch + public static final int MIN_VALUE = 0; + + /** + * The bit sequence of the byte. + */ + @DoNotTouch + private final MyBit[] bits = new MyBit[NUMBER_OF_BITS]; + + /** + * The integer value of the byte. + */ + @DoNotTouch + private int value; + + /** + * Constructs a new byte with the default value of 0. + */ + @DoNotTouch + public MyByte() { + this(0); + } + + /** + * Constructs a new byte with the specified value. + * + * @param value the value of the byte + * + * @throws IllegalArgumentException if the value is not between the {@value MIN_VALUE} and {@value MAX_VALUE} + */ + @DoNotTouch + public MyByte(int value) { + if (value < MIN_VALUE || value > MAX_VALUE) { + throw new IllegalArgumentException( + "Value must be between %s and %s: %s".formatted(MIN_VALUE, MAX_VALUE, value) + ); + } + this.value = value; + for (int i = 0; i < NUMBER_OF_BITS; i++) { + // Reverse the bit indexing here + bits[i] = MyBit.fromInt((value >> (NUMBER_OF_BITS - i - 1)) & 1); + } + } + + /** + * Returns the integer value of the byte. + * + * @return the integer value of the byte + */ + @DoNotTouch + public int intValue() { + return value; + } + + /** + * Returns the bit sequence of the byte. + * The bits are ordered from left to right, more formally from the most significant bit to the least significant + * bit; e.g., 10000000 will be represented as [1, 0, 0, 0, 0, 0, 0, 0]. + * + * @return the bit sequence of the byte + */ + @DoNotTouch + public MyBit[] getBits() { + return bits; + } + + /** + * Decreases the value of the byte by the specified amount. + * + * @param n the amount to decrease the value by + * + * @return the decreased byte + * @throws IllegalArgumentException if the value cannot be decreased below {@value MIN_VALUE} + */ + @DoNotTouch + public MyByte decrease(int n) { + if (value - n < MIN_VALUE) { + throw new IllegalArgumentException("Value cannot be decreased below min value %s!".formatted(MIN_VALUE)); + } + value -= n; + for (int i = 0; i < NUMBER_OF_BITS; i++) { + bits[i] = MyBit.fromInt((value >> (NUMBER_OF_BITS - i - 1)) & 1); + } + return this; + } + + /** + * Decreases the value of the byte by 1. + * + * @return the decreased byte + */ + @DoNotTouch + public MyByte decrease() { + return decrease(1); + } + + /** + * Increases the value of the byte by the specified amount. + * + * @param n the amount to increase the value by + * + * @return the increased byte + * @throws IllegalArgumentException if the value cannot be increased above {@value MAX_VALUE} + */ + @DoNotTouch + public MyByte increase(int n) { + if (value + n > MAX_VALUE) { + throw new IllegalArgumentException("Value cannot be increased above max value %s!".formatted(MAX_VALUE)); + } + value += n; + for (int i = 0; i < NUMBER_OF_BITS; i++) { + // Reverse bit indexing here as well + bits[i] = MyBit.fromInt((value >> (NUMBER_OF_BITS - i - 1)) & 1); + } + return this; + } + + /** + * Increases the value of the byte by 1. + * + * @return the increased byte + */ + @DoNotTouch + public MyByte increase() { + return increase(1); + } + + /** + * Returns the bit at the specified index. + * + * @param index the index of the bit to return + * + * @return the bit at the specified index + * @throws IllegalArgumentException if the index is out of bounds + */ + @DoNotTouch + public MyBit get(int index) { + if (index < 0 || index >= NUMBER_OF_BITS) { + throw new IllegalArgumentException("Index must be between %s and %s: %s".formatted(MIN_POSITION, MAX_POSITION, index)); + } + // Reverse index when accessing the bit + return bits[NUMBER_OF_BITS - index - 1]; + } + + /** + * Sets the bit at the specified index. + * + * @param index the index of the bit to set + * @param bit the bit to set + * + * @throws IllegalArgumentException if the index is out of bounds + */ + @DoNotTouch + public void set(int index, MyBit bit) { + if (index < 0 || index >= NUMBER_OF_BITS) { + throw new IllegalArgumentException("Index must be between %s and %s: %s".formatted(MIN_POSITION, MAX_POSITION, index)); + } + // Reverse index when setting the bit + MyBit old = bits[NUMBER_OF_BITS - index - 1]; + bits[NUMBER_OF_BITS - index - 1] = bit; + if (old == bit) { + return; + } + if (bit == MyBit.ZERO) { + // Clear the bit at the correct index + value = value & ~(1 << index); + } else { + // Set the bit at the correct index + value = value | (1 << index); + } + } + + @DoNotTouch + @Override + public boolean equals(Object o) { + return this == o || o instanceof MyByte aMyByte && value == aMyByte.value; + } + + @DoNotTouch + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + @DoNotTouch + @Override + public String toString() { + return "Byte{value=%s, bits=%s}".formatted( + value, + Arrays.stream(bits) + .map(MyBit::intValue) + .map(String::valueOf) + .collect(Collectors.joining()) + ); + } +} diff --git a/H12/src/main/java/h12/lang/MyBytes.java b/H12/src/main/java/h12/lang/MyBytes.java new file mode 100644 index 0000000..3ab02a3 --- /dev/null +++ b/H12/src/main/java/h12/lang/MyBytes.java @@ -0,0 +1,112 @@ +package h12.lang; + +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * Utility class for converting between bytes and other types. + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public final class MyBytes { + + /** + * Buffer used for converting between bytes and other types. + */ + @DoNotTouch + private static final ByteBuffer buffer = ByteBuffer.allocate(4); + + /** + * Prevent instantiation of this utility class. + */ + @DoNotTouch + private MyBytes() { + } + + /** + * Convert an integer to a 4-byte array. + * + * @param value the integer to convert + * + * @return the 4-byte array representing the integer + */ + @DoNotTouch + public static byte[] toBytes(int value) { + return buffer.clear().putInt(value).array(); + } + + /** + * Convert a character to a 4-byte array. + * + * @param bytes the character to convert + * + * @return the 4-byte array representing the character + */ + @DoNotTouch + public static int toInt(byte[] bytes) { + return buffer.clear().put(bytes).flip().getInt(); + } + + /** + * Convert a 4-byte array to a character. + * + * @param bytes the 4-byte array to convert + * + * @return the character represented by the 4-byte array + */ + @DoNotTouch + public static char toChar(byte[] bytes) { + return (char) toInt(bytes); + } + + /** + * Convert a byte array to a bit sequence array. + * + * @param bytes the byte array to convert + * + * @return the bit sequence array representing the byte array + */ + public static MyBit[] toBits(byte[] bytes) { + MyBit[] bits = new MyBit[bytes.length * MyByte.NUMBER_OF_BITS]; + int offset = -java.lang.Byte.MIN_VALUE; + int index = 0; + for (byte b : bytes) { + MyByte value = new MyByte(b + offset); + for (int i = MyByte.NUMBER_OF_BITS - 1; i >= 0; i--) { + bits[index++] = value.get(i); + } + } + return bits; + } + + /** + * Returns a string representation of the byte array in binary format. + * + * @param bytes the byte array to convert + * + * @return the string representation of the byte array in binary format + */ + public static String toBinaryString(byte[] bytes) { + return Arrays.stream(toBits(bytes)) + .map(MyBit::intValue) + .map(String::valueOf) + .collect(Collectors.joining()); + } + + /** + * Returns the number of missing bits to fill the byte. + * + *

E.g. if the length is 5, then the number of missing bits is 3 to fill the byte. + * + * @param length the length of the byte array + * + * @return the number of missing bits to fill the byte + */ + public static int computeMissingBits(int length) { + return (MyByte.NUMBER_OF_BITS - (length % MyByte.NUMBER_OF_BITS)) % MyByte.NUMBER_OF_BITS; + } +} diff --git a/H12/src/main/java/h12/util/TreeNode.java b/H12/src/main/java/h12/util/TreeNode.java new file mode 100644 index 0000000..944737d --- /dev/null +++ b/H12/src/main/java/h12/util/TreeNode.java @@ -0,0 +1,173 @@ +package h12.util; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.student.annotation.DoNotTouch; + +/** + * Represents a node in a binary tree. + * + * @param the type of the value stored in the node + * + * @author Per Göttlicher, Nhan Huynh + */ +@DoNotTouch +public class TreeNode { + + /** + * The left child of this node. + */ + @DoNotTouch + private @Nullable TreeNode left; + + /** + * The right child of this node. + */ + @DoNotTouch + private @Nullable TreeNode right; + + /** + * The parent of this node. + */ + @DoNotTouch + private @Nullable TreeNode parent; + + /** + * The value stored in this node. + */ + @DoNotTouch + private final @Nullable T value; + + /** + * Constructs a new tree node with the given children, parent and value. + * + * @param left the left child of the node + * @param right the right child of the node + * @param parent the parent of the node + * @param value the value stored in the node + */ + @DoNotTouch + public TreeNode( + @Nullable TreeNode left, + @Nullable TreeNode right, + @Nullable TreeNode parent, + @Nullable T value + ) { + this.left = left; + this.right = right; + this.parent = parent; + this.value = value; + } + + /** + * Constructs a new tree node with the given children and value. + * + * @param left the left child of the node + * @param right the right child of the node + * @param value the value stored in the node + */ + @DoNotTouch + public TreeNode(TreeNode left, TreeNode right, T value) { + this(left, right, null, value); + } + + /** + * Constructs a new tree node with the given children and parent. + * + * @param left the left child of the node + * @param right the right child of the node + */ + @DoNotTouch + public TreeNode(TreeNode left, TreeNode right) { + this(left, right, null); + } + + /** + * Constructs a new tree node with the given value. + * + * @param value the value stored in the node + */ + @DoNotTouch + public TreeNode(@Nullable T value) { + this(null, null, value); + } + + /** + * Returns the left child of this node. + * + * @return the left child of this node + */ + @DoNotTouch + public @Nullable TreeNode getLeft() { + return left; + } + + /** + * Sets the left child of this node. + * + * @param left the left child of this node + */ + @DoNotTouch + public void setLeft(@Nullable TreeNode left) { + this.left = left; + } + + /** + * Returns the right child of this node. + * + * @return the right child of this node + */ + @DoNotTouch + public @Nullable TreeNode getRight() { + return right; + } + + /** + * Sets the right child of this node. + * + * @param right the right child of this node + */ + @DoNotTouch + public void setRight(@Nullable TreeNode right) { + this.right = right; + } + + /** + * Returns the parent of this node. + * + * @return the parent of this node + */ + @DoNotTouch + public @Nullable TreeNode getParent() { + return parent; + } + + /** + * Sets the parent of this node. + * + * @param parent the parent of this node + */ + @DoNotTouch + public void setParent(@Nullable TreeNode parent) { + this.parent = parent; + } + + /** + * Returns the value stored in this node. + * + * @return the value stored in this node + */ + @DoNotTouch + public @Nullable T getValue() { + return value; + } + + /** + * Returns whether this node is a leaf node. + * + * @return {@code true} if this node is a leaf node, {@code false} otherwise + */ + @DoNotTouch + public boolean isLeaf() { + return left == null && right == null; + } +} diff --git a/H12/src/test/java/h12/ExampleJUnitTest.java b/H12/src/test/java/h12/ExampleJUnitTest.java new file mode 100644 index 0000000..75a95c4 --- /dev/null +++ b/H12/src/test/java/h12/ExampleJUnitTest.java @@ -0,0 +1,16 @@ +package h12; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * An example JUnit test class. + */ +public class ExampleJUnitTest { + + @Test + public void testAddition() { + assertEquals(2, 1 + 1); + } +} diff --git a/solution/H02/src/graderPrivate/java/h02/FourWinsTest.java b/solution/H02/src/graderPrivate/java/h02/FourWinsTest.java index 7df3635..2113ad5 100644 --- a/solution/H02/src/graderPrivate/java/h02/FourWinsTest.java +++ b/solution/H02/src/graderPrivate/java/h02/FourWinsTest.java @@ -565,7 +565,7 @@ public class FourWinsTest { int worldHeight = 5; int worldWidth = 5; FourWins fourWins = new FourWins(worldWidth, worldHeight); - InputHandler inputHandler = fourWins.getInputHandler(); + InputHandler inputHandler = fourWins.inputHandler; for (int i = 0; i < 10; i++) { inputHandler.addInput(0); } @@ -614,7 +614,7 @@ public class FourWinsTest { int worldWidth = 5; try (MockedStatic mockedStatic = Mockito.mockStatic(FourWins.class, answer)) { FourWins fourWins = new FourWins(worldWidth, worldHeight); - InputHandler inputHandler = fourWins.getInputHandler(); + InputHandler inputHandler = fourWins.inputHandler; for (int i = 0; i < 10; i++) { inputHandler.addInput(i % worldWidth); } @@ -670,7 +670,7 @@ public class FourWinsTest { int worldWidth = 5; try (MockedStatic mockedStatic = Mockito.mockStatic(FourWins.class, answer)) { FourWins fourWins = new FourWins(worldWidth, worldHeight); - InputHandler inputHandler = fourWins.getInputHandler(); + InputHandler inputHandler = fourWins.inputHandler; for (int i = 0; i < 10; i++) { inputHandler.addInput(i % worldWidth); } diff --git a/solution/H03/build.gradle.kts b/solution/H03/build.gradle.kts index 1f8acc6..88fb20f 100644 --- a/solution/H03/build.gradle.kts +++ b/solution/H03/build.gradle.kts @@ -26,6 +26,8 @@ submission { } dependencies { + implementation("org.tudalgo:algoutils-tutor:0.9.1-FPI-SNAPSHOT") + implementation("org.tudalgo:algoutils-student:0.9.1-FPI-SNAPSHOT") implementation(libs.algoutils.student) implementation(libs.fopbot) } diff --git a/solution/H03/gradle/libs.versions.toml b/solution/H03/gradle/libs.versions.toml index fc61595..00553b7 100644 --- a/solution/H03/gradle/libs.versions.toml +++ b/solution/H03/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -algoutils = "0.9.1-SNAPSHOT" +algoutils = "0.9.1-FPI-SNAPSHOT" [plugins] algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } diff --git a/solution/H03/src/graderPrivate/java/h03/H03_RubricProvider.java b/solution/H03/src/graderPrivate/java/h03/H03_RubricProvider.java index 6a0bedd..0179696 100644 --- a/solution/H03/src/graderPrivate/java/h03/H03_RubricProvider.java +++ b/solution/H03/src/graderPrivate/java/h03/H03_RubricProvider.java @@ -270,7 +270,7 @@ public class H03_RubricProvider implements RubricProvider { @Override public void configure(RubricConfiguration configuration) { - configuration.addTransformer(() -> new SolutionMergingClassTransformer.Builder("h03") + configuration.addTransformer(new SolutionMergingClassTransformer.Builder("h03") .addSolutionClass("h03.Main") .addSolutionClass("h03.RobotsChallenge", "h03.robots.RobotsChallenge", "robots.RobotsChallenge") .addSolutionClass("h03.robots.DoublePowerRobot", "h03.DoublePowerRobot", "robot.DoublePowerRobot") diff --git a/solution/H04/build.gradle.kts b/solution/H04/build.gradle.kts index bdd69a3..8efd014 100644 --- a/solution/H04/build.gradle.kts +++ b/solution/H04/build.gradle.kts @@ -27,6 +27,8 @@ submission { dependencies { implementation(libs.fopbot) + implementation("org.tudalgo:algoutils-student:0.9.1-FPI-SNAPSHOT") + implementation("org.tudalgo:algoutils-tutor:0.9.1-FPI-SNAPSHOT") } jagr { diff --git a/solution/H04/gradle/libs.versions.toml b/solution/H04/gradle/libs.versions.toml index fc61595..00553b7 100644 --- a/solution/H04/gradle/libs.versions.toml +++ b/solution/H04/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -algoutils = "0.9.1-SNAPSHOT" +algoutils = "0.9.1-FPI-SNAPSHOT" [plugins] algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } diff --git a/solution/H04/src/graderPrivate/java/h04/H04_RubricProvider.java b/solution/H04/src/graderPrivate/java/h04/H04_RubricProvider.java index 2be1bdf..ab35f88 100644 --- a/solution/H04/src/graderPrivate/java/h04/H04_RubricProvider.java +++ b/solution/H04/src/graderPrivate/java/h04/H04_RubricProvider.java @@ -170,7 +170,7 @@ public class H04_RubricProvider implements RubricProvider { @Override public void configure(RubricConfiguration configuration) { - configuration.addTransformer(() -> new SolutionMergingClassTransformer.Builder("h04") + configuration.addTransformer(new SolutionMergingClassTransformer.Builder("h04") .addSolutionClass("h04.chesspieces.Bishop") .addSolutionClass("h04.chesspieces.ChessPiece") .addSolutionClass("h04.chesspieces.Families") diff --git a/solution/H05/build.gradle.kts b/solution/H05/build.gradle.kts index 81616b6..03469d2 100644 --- a/solution/H05/build.gradle.kts +++ b/solution/H05/build.gradle.kts @@ -9,6 +9,11 @@ exercise { assignmentId.set("h05") } +dependencies { + implementation("org.tudalgo:algoutils-tutor:0.9.1-FPI-SNAPSHOT") + implementation("org.tudalgo:algoutils-student:0.9.1-FPI-SNAPSHOT") +} + submission { // ACHTUNG! // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen diff --git a/solution/H05/gradle/libs.versions.toml b/solution/H05/gradle/libs.versions.toml index 2d7f5b4..f44b59b 100644 --- a/solution/H05/gradle/libs.versions.toml +++ b/solution/H05/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -algoutils = "0.9.1-SNAPSHOT" +algoutils = "0.9.1-FPI-SNAPSHOT" [libraries] annotations = "org.jetbrains:annotations:24.1.0" diff --git a/solution/H05/src/graderPrivate/java/h05/H05_RubricProvider.java b/solution/H05/src/graderPrivate/java/h05/H05_RubricProvider.java index 83a4606..fe79d8d 100644 --- a/solution/H05/src/graderPrivate/java/h05/H05_RubricProvider.java +++ b/solution/H05/src/graderPrivate/java/h05/H05_RubricProvider.java @@ -215,7 +215,7 @@ public class H05_RubricProvider implements RubricProvider { @Override public void configure(RubricConfiguration configuration) { - configuration.addTransformer(() -> new SolutionMergingClassTransformer.Builder("h05") + configuration.addTransformer(new SolutionMergingClassTransformer.Builder("h05") .addSolutionClass("h05.Airspace") .addSolutionClass("h05.CargoPlane") .addSolutionClass("h05.CargoStack") diff --git a/solution/H07/.gradle/8.10.2/checksums/checksums.lock b/solution/H07/.gradle/8.10.2/checksums/checksums.lock new file mode 100644 index 0000000000000000000000000000000000000000..9e6dc3009c0f061fa0c7e1fb03c71823cfbc59f1 GIT binary patch literal 17 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 Q!txnd4^%M=omtBN0p*T_4gdfE literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$BundleAccessors.class b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$BundleAccessors.class new file mode 100644 index 0000000000000000000000000000000000000000..9ca7e17518a8b83fa87e01018ff91cc334ce989e GIT binary patch literal 765 zcmbVKO>Yx15Pc45mWGr5Va+{n46u9ZIh3 zX@1E?THp`YF%t<_u4J)i3+HdZ8<`&Q1vOPVXNfNO!94#P`b!$6Brb0fM|)h?O`^Qw z{&Mf1w~{1xp&f{}jFlbGgmPE8G(8E4lHPwt5?KzPoM*Ug@M^UaMZqx!QD$vNE*BEV zaTrAXxaem88e`BNXx9w3N6zy}Q|BxnXQ>)=KZHgK9=ciZXkF;wlCH?0ckDgOprRN# zX4p39ucq=}FK)2)+nZ2GS_OeDiMy9`VHjGaFm%46hw5MK2ZSU!` r=P!2KyBl9%KL0{>b)BJrx5~VuwuK(H)b6O)!d=``g$(!c0GmGnzIE@y literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$PluginAccessors.class b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$PluginAccessors.class new file mode 100644 index 0000000000000000000000000000000000000000..126131c2452ef13853669f7a441bbdc939b9424c GIT binary patch literal 967 zcmbVL%Wl&^6g}g#agwGK0_6>Dr7qHfm<>Wmt|~=oBO!%SDbW4I9;`vmOf)mD$X~$* zBo=%CABDJy(-Pb)DmM2u_gtU*@UP!Legb%jodyC_Laa2giYmi9V^f}5kz|sKvEoX5 zX|>3BEWF4}$~!~nt%&{c=i=c=j-^hdjwd~e8avrN&GJ;~xyMjFP+IvzhPd4?6(3u3 zt`cea>D-uuqH^LD7Dw`<$TNQ?ty4yK3vSWgSq(LYn#fW!5?(gYz*>lA6YIFa@Ots{ zaV(uP*70P-`)X)~Rnqm0CELwg=v?G5G-E5NV9^@Gt9JjBI2SwdnB;BTA!v~t%%b6bEBuD~ms0XuY*Hk^T}ryQ479NX^x+Z|;QkE$01rvG Rs8E1Mc!D}ne~N9?{{Zzy40`|o literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$VersionAccessors.class b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs$VersionAccessors.class new file mode 100644 index 0000000000000000000000000000000000000000..5d7fe22910dca88da3a8e1d517e3e762dc5a72a0 GIT binary patch literal 601 zcmbVJOG`pQ6#hodn`UZO>j+xdgJ#o4j6gIYkPr&@bLXC9;yNQUSIM8%DrnIU=to6k zUc;(!Sx-Q4a(eax_WTu4^n4xwG3> S?Pbkt8I)1=$pLn-i^3=NFS85) literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs.class b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibs.class new file mode 100644 index 0000000000000000000000000000000000000000..01a54ab9e5760d5688d87361a00dfe0003e48c37 GIT binary patch literal 2597 zcmb_eTTc@~6#fRGwRKTMQ3~Ecg(|KJUcpN#peRA&g~Z3{c4)?IcbnN=lvjU|CK3`& z`~m(b!Jt?kKLMRIiqbr3@q zj$)W0Rj&uRIBmLCKWnL#)^Oay2u=`09N*iLC5AhucuQpM5t7CrMm1(L3{DHoI{NUB z*5VqDTR4T&3@5j_<4}#v6frd8v7WkiwQb2S)#oh3-LC7i7gJ> zsW_8nyzTCXuFFLWmvEWk=SIVYuI9XJ617vV_^W zUNF1iMkVPrFq_6KMm0L_Sh$OOelahwa!g9XJqXi-{v1^{^?O-uT}{uJ5&<&VMSaIrkdN|zR5G&1!+r@ zwm7GxY@rurW+h@>aqzwBYE4=Cl^-cbtVo@v5pynG)2U$?Z^8}zE3Et8dgQvfilor2 zRgXqj-sM3c$e|%KdMbz!1ML`|;5>n&kN#8oF|21Nt%h|Au2KSZl@fBQ95gMFAnyD0 z^^xQfL^rcnuFhooGXr~I+3YTo*>4zpoBe_#^c>s6$z6=m))~EZuD(rllAftOT-}9D z$FqM(+}g$M&!m}pJ-x@OR?d=dqZmR46ST94alFAfEYNv^_#RZbAL0?MwQr}1GNJ=y zW9(D)P^;3cpe9U>5IK6AthUKILrjavw_&|)vd-ZEmPmUamK$!Z(DxI1#^`L2()AQ6 P>YoR(N_3X!Go*e2eBU1E literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock$BundleAccessors.class b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock$BundleAccessors.class new file mode 100644 index 0000000000000000000000000000000000000000..aabb2a3bb8bab7eb59ed152b60e77263ea1d1f11 GIT binary patch literal 891 zcmbVL!EO^V5Pc45mWGr-Peb%7i*G(H0*5pso0HAvL!NbhzIRYrMlVMKtykLW_*#h8qwxju(&c32 zae7KwT;}&K=FGf1(>ZxLSvr49yj1BSov6yhDfytC9W3g<#J_^67`;xbNI{OuvWhA- z)L+eAxvKI}pRfW!=E2B;nyFM99p^_bs>th4ln>;4kEaQ)3k=tl$TAASc}A9UtW&SN zrob8OhmoC_s?atZ7?*uqYTG|Y2s8(*p}_W7TRN)Bl>CRfaDn!FSNV*Fx*k0IH|_IN zb*31?XX%L#nsR~eyUIpg(o_dsD`D+&BSBzyTmz(0wvfLuJ%P^1TJi&c10r{ZEyj-^SYi6=ce&Fp0JQ0J*K<&L4cqm1&q3~{@^AU?L) zu}Y-nhvlLqMT@{QF81Vmk!yb>ty7ul7T%(*qZ(=qHKEgNB)n{(ft3)=CRTBYp*R2e zIF`<3*70P-`)X)~RnifH)^6VvHMkc#i$9hHbxs%z&DctkFF*{>+x-vXSa2;&$_L&m zlSW&MC7h`>s^K!jvhx!y8J4*e-1t>f7ZpX9ycQ=-$lM7`TLM%u0x z&Pf;I9z$n7mj8Nk46B9H^8JKZr&Q);PqO=W+LS?|b(%Le=otm{w*VDTVyM!1g?8(- zuh1NBKYsEJ>~Z84#3&md2q g0Y%3r0l=9{T5&Ri5>}n8IW2=SsxH~X8rD(x0Bn%M#sB~S literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.class b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/classes/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.class new file mode 100644 index 0000000000000000000000000000000000000000..6051b7d6cff82d02542f6f56ac90981a4478e9df GIT binary patch literal 3963 zcmb_fTX)k&5dIdDI5DCGw?F~~1f(Si7jY|>ngVu6f*~Y<5L0?fWqG44$SYTp4SDS^ zYR_pxPkT-e&;3z7os}%xkz*1P9;8|AWoCBfn~VPa@2`IVTtkq?9_&q_M?)|A7;>&> z8@6Yb9d4LaVF(#;PnwQlnStrJwvj9OfoEF5<$a+`1@p&zNrv8nQYzR@^dojJeWFZUx=;G_Pa^ zfhS6}fcr+FQmF-I$>F)?+}6jvKrGXpeWUC<#)MflOTrPs>Z}`>0bOR^^nC7R$BF~! z$3O~c4f~)mTyM9DWpUqkJ>pR@W<<#|J;D7c*Q2ptkn>K>7Shi35#eYo0ILIxzOSzg5#KR1 z#8w8F#8e8?8Xlm)&tiH4d`o$I+CR(2FgpZy_XtZSPGGr z#uGeEVL`()EHXU#0H7tH&_yRIhsxNCRn<`P=^C|g3)GmA)(mGy3!A~Qh0v&pqvY_M z;n6NtbFEs1%cw0&qlgz8zQgxa@uX=lQj^B8cXX`C&@(~(Bg26iGU#lrQsUk-)f6%e zKds4tEL{}7P+g*wjV6zZ<)QE%Z>UvPU8hk938jR6Hjn#S+VyCo(%O;=Dk~%HmT(nf=WBTjGlf zEeyxnGlcqSnRVrC&2e&7K@7Emq^^0wF@2wtvV)zS*@1)=2mlGaQm8WA+A#02CG!%><#p{DeBn&=2Uqi=D34F)Y=Z9DPR z8m|9NoEd(k_t8+wNz!cygBZpcn#toB7NO%OTJNKMOX2RHVbWOXcAO|9+DkHy{uVAO zR%$D#ucVR%3wy(@cZjOl)0waT#O+Le9rxd1avcu``!loan16@jI=&@7MvIU7wFNGb zn9C^B2u(#ejTx3<(>tli^%jFjk((rXg%0e2Xfk+7->>MoLdxzZ3p*H~F0vmLqF0GZ TqLXm(3(+S;J)%XTJ_h~=+L`&p literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/metadata.bin b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/metadata.bin new file mode 100644 index 0000000..71fcfcb --- /dev/null +++ b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/metadata.bin @@ -0,0 +1 @@ +›tajbjehwvzefbn4rpr56ei3key—æŠÚA'ÿœ–š*m÷I:ˆclassesˆ•>ˆ#D¿18#¬´aˆsources.<Ò°—ÔŸÁbQª0Úˆ \ No newline at end of file diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibs.java b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibs.java new file mode 100644 index 0000000..8c97a4d --- /dev/null +++ b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibs.java @@ -0,0 +1,89 @@ +package org.gradle.accessors.dm; + +import org.gradle.api.NonNullApi; +import org.gradle.api.artifacts.MinimalExternalModuleDependency; +import org.gradle.plugin.use.PluginDependency; +import org.gradle.api.artifacts.ExternalModuleDependencyBundle; +import org.gradle.api.artifacts.MutableVersionConstraint; +import org.gradle.api.provider.Provider; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.ProviderFactory; +import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory; +import org.gradle.api.internal.catalog.DefaultVersionCatalog; +import java.util.Map; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import javax.inject.Inject; + +/** + * A catalog of dependencies accessible via the {@code libs} extension. + */ +@NonNullApi +public class LibrariesForLibs extends AbstractExternalDependencyFactory { + + private final AbstractExternalDependencyFactory owner = this; + private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config); + private final BundleAccessors baccForBundleAccessors = new BundleAccessors(objects, providers, config, attributesFactory, capabilityNotationParser); + private final PluginAccessors paccForPluginAccessors = new PluginAccessors(providers, config); + + @Inject + public LibrariesForLibs(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { + super(config, providers, objects, attributesFactory, capabilityNotationParser); + } + + /** + * Group of versions at versions + */ + public VersionAccessors getVersions() { + return vaccForVersionAccessors; + } + + /** + * Group of bundles at bundles + */ + public BundleAccessors getBundles() { + return baccForBundleAccessors; + } + + /** + * Group of plugins at plugins + */ + public PluginAccessors getPlugins() { + return paccForPluginAccessors; + } + + public static class VersionAccessors extends VersionFactory { + + public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); } + + } + + public static class BundleAccessors extends BundleFactory { + + public BundleAccessors(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); } + + } + + public static class PluginAccessors extends PluginFactory { + + public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); } + + /** + * Plugin provider for algomate with plugin id org.tudalgo.algomate and + * with version 0.7.1 + *

+ * This plugin was declared in catalog libs.versions.toml + */ + public Provider getAlgomate() { return createPlugin("algomate"); } + + /** + * Plugin provider for style with plugin id org.sourcegrade.style and + * with version 3.0.0 + *

+ * This plugin was declared in catalog libs.versions.toml + */ + public Provider getStyle() { return createPlugin("style"); } + + } + +} diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.java b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.java new file mode 100644 index 0000000..27443a0 --- /dev/null +++ b/solution/H07/.gradle/8.10.2/dependencies-accessors/700afc2217d5ebd6a4de719b82fc768475ac4788/sources/org/gradle/accessors/dm/LibrariesForLibsInPluginsBlock.java @@ -0,0 +1,97 @@ +package org.gradle.accessors.dm; + +import org.gradle.api.NonNullApi; +import org.gradle.api.artifacts.MinimalExternalModuleDependency; +import org.gradle.plugin.use.PluginDependency; +import org.gradle.api.artifacts.ExternalModuleDependencyBundle; +import org.gradle.api.artifacts.MutableVersionConstraint; +import org.gradle.api.provider.Provider; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.ProviderFactory; +import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory; +import org.gradle.api.internal.catalog.DefaultVersionCatalog; +import java.util.Map; +import org.gradle.api.internal.attributes.ImmutableAttributesFactory; +import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser; +import javax.inject.Inject; + +/** + * A catalog of dependencies accessible via the {@code libs} extension. + */ +@NonNullApi +public class LibrariesForLibsInPluginsBlock extends AbstractExternalDependencyFactory { + + private final AbstractExternalDependencyFactory owner = this; + private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config); + private final BundleAccessors baccForBundleAccessors = new BundleAccessors(objects, providers, config, attributesFactory, capabilityNotationParser); + private final PluginAccessors paccForPluginAccessors = new PluginAccessors(providers, config); + + @Inject + public LibrariesForLibsInPluginsBlock(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { + super(config, providers, objects, attributesFactory, capabilityNotationParser); + } + + /** + * Group of versions at versions + */ + public VersionAccessors getVersions() { + return vaccForVersionAccessors; + } + + /** + * Group of bundles at bundles + * + * @deprecated Will be removed in Gradle 9.0. + */ + @Deprecated + public BundleAccessors getBundles() { + org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser(); + return baccForBundleAccessors; + } + + /** + * Group of plugins at plugins + */ + public PluginAccessors getPlugins() { + return paccForPluginAccessors; + } + + public static class VersionAccessors extends VersionFactory { + + public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); } + + } + + /** + * @deprecated Will be removed in Gradle 9.0. + */ + @Deprecated + public static class BundleAccessors extends BundleFactory { + + public BundleAccessors(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); } + + } + + public static class PluginAccessors extends PluginFactory { + + public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); } + + /** + * Plugin provider for algomate with plugin id org.tudalgo.algomate and + * with version 0.7.1 + *

+ * This plugin was declared in catalog libs.versions.toml + */ + public Provider getAlgomate() { return createPlugin("algomate"); } + + /** + * Plugin provider for style with plugin id org.sourcegrade.style and + * with version 3.0.0 + *

+ * This plugin was declared in catalog libs.versions.toml + */ + public Provider getStyle() { return createPlugin("style"); } + + } + +} diff --git a/solution/H07/.gradle/8.10.2/dependencies-accessors/gc.properties b/solution/H07/.gradle/8.10.2/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/solution/H07/.gradle/8.10.2/executionHistory/executionHistory.bin b/solution/H07/.gradle/8.10.2/executionHistory/executionHistory.bin new file mode 100644 index 0000000000000000000000000000000000000000..8bb310d5eb2e2b6f7c546ef36a983653816eba82 GIT binary patch literal 118101 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 literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/executionHistory/executionHistory.lock b/solution/H07/.gradle/8.10.2/executionHistory/executionHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..84cd24f68652f877e1478c3f6197a727ce523af1 GIT binary patch literal 17 TcmZR+;J(i|xmLT80RqGTF1Q1( literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/fileChanges/last-build.bin b/solution/H07/.gradle/8.10.2/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/fileHashes/fileHashes.bin b/solution/H07/.gradle/8.10.2/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..a64a10fe6b32fa59505ee71c4fde88973d7797d1 GIT binary patch literal 22547 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 literal 0 HcmV?d00001 diff --git a/solution/H07/.gradle/8.10.2/fileHashes/resourceHashesCache.bin b/solution/H07/.gradle/8.10.2/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..6cd958e13b583bbd152e92e39eb95bb25c974123 GIT binary patch literal 19857 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 + + + + + \ No newline at end of file diff --git a/solution/H07/.idea/codeStyles/codeStyleConfig.xml b/solution/H07/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/solution/H07/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/solution/H07/.idea/compiler.xml b/solution/H07/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/solution/H07/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/solution/H07/.idea/gradle.xml b/solution/H07/.idea/gradle.xml new file mode 100644 index 0000000..ce1c62c --- /dev/null +++ b/solution/H07/.idea/gradle.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/solution/H07/.idea/misc.xml b/solution/H07/.idea/misc.xml new file mode 100644 index 0000000..7c47dd4 --- /dev/null +++ b/solution/H07/.idea/misc.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/solution/H07/.idea/sbt.xml b/solution/H07/.idea/sbt.xml new file mode 100644 index 0000000..2616292 --- /dev/null +++ b/solution/H07/.idea/sbt.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/solution/H07/.idea/vcs.xml b/solution/H07/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/solution/H07/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/solution/H07/build/classes/java/graderPrivate/h07/ArithmeticExpressionTest.class b/solution/H07/build/classes/java/graderPrivate/h07/ArithmeticExpressionTest.class new file mode 100644 index 0000000000000000000000000000000000000000..c969027d4092c8916ed32c1f80584c452865c5d0 GIT binary patch literal 1024 zcmaizU2hUW7=_OO?FuZke6*zs^;_Heu_nfNfzc48k%ZC)ka*V&%M=D-m&`6kf0ka< z#0!6bKg#&dvbLm_xSP!E?40*GXJ%)A{r>S2Km|_{h#+bpW?}`a4C^EQiCbgt46LKx zNZ3BZ>MQ9;|20E&cdr}AHN*`hOeA44WQWgQTGcW4yp}i>N;tM)*r>GXop*<|PQ7|k z`*7TCTm=C$(;+@xIcjQL4cGQXSc6kk%OrCbo5k{5(UGPelJbh*lM}s%WC5Ri(Kq z3|MzUOt_QlL_Dr&`(b*)w;+7~qwv#X`wsr`cyF%y`%olx~W~ zqp8h;?^Xx)hYp46Vxf3{T`-l1#{26F^h{NjKs0`!YF9KKslO>ORocc-G8*n09x@e^ zY0zhIsIS>mj&jWK!cb7m6wJvjwSC`y;wC7ruGv#Yz-AkmgSi6FP$+zWppC~sjhbg* zz8)114VtQBp@BuXgk%S}Rzdxg7n=i0vAfj3WmqgQlIbBcp_OJP1zUeo5Ebt$3@kyV zplr~w6Eglu&{aH_8TbUM1oJvNo3}M@Z)t1Z*4xq0w5wr9bC7V`AS%193q+Ht`Wd(i z%e|;JP=i{*EUk|0XMr!8qE*wr1q-WdT+}U2KRK+#Dlb+WsKeD%Q;tJsh`>7#O17Ct zY~}VSifavAhc(nvTzAjU@YY6eTSC1T*XJ3C?F;2tj}2aIG*FLCRK&Dwxq~JZ>euEh zD6;wldkT16&6I6NJBo{WeK|H`ix*oBG@y~1R-WHwCR5b(%%t}1)=(-uU=rUQ)0SXR zv8Zzxamw}BW}q3{34FhqQhqD2swcIWd{$EjAR8pS*eSSSTFS}rQ0Dwe1G^BQox~V< z1Y0Jx2zLn14_)Qhfi?r}=n$0WhS6Q}3{bl{f$T)ki!KAZu}3gF7pnAk8{IaB9YMbR zIziiq8!5Qbb~)Cf$G}avnI2`vBgwtd)PP_?A&vKVaVzD?P1bxQY!0b>qO!RJ#0%3vANmCwCj&V%kD0JjR73XhS_V0Da40q0WW`h3D>o99DYA2D z>-|idQ3LxyrOl)fb|lOuYjDtvGX`{52gWDB`YBJ9V;M{j4aJydsj)By4a8wlz4juz z5^3t^uIirYu4Jlo1;nc9QK~y=AfZy;Oj|IQ`cekcIK=21wvlg4M`IBc5*nwifGUSa zy$?qiM9m{Z%&lgmQsq(xz8N@*+r7BMz^8GiVDt2}oSB3-KA;)AMO{-&5p{X*m8UZ4|?&Cfrs%(CcWr{*N{krh8dSj z8JEq_pkQ_NO@*Y-B{+Mas?j)}CNFr@z+-q^P!gg=4hxoK!it`uFCEu~VcmA;fywi8 zc*2V(4LpU<3l>eln*a}nhFE|)08hZpouBh%^Wkacxs{dW_#&S5;yDA);|0NGj-ot1%3ba|N zwsb5ec-alH<0(@OJ(=J;Rk}hUYrN(AQH=8{q<>A&JV~tVP^b4o1tw8=yl>ze_*teN zdua2)bSOsKJ5vaboCbeN0rKEO13!nKXWCCO?F-gSkm_ZQl@sBUo`Md z{1U5$P%NekJHb-7-xMIL>G7ik=lv)})X&`&pM1*Z*5cO;{JN@OW~8iub(p)DP}20H z4Cj6LEy1;puT-k2SsAg+WM$k+Rq9HxG8;b~_tS$``|vx0OPZ{7ETYG<5Q$WV)rPk6 z%H(P_R$pa`&#EdME1l}k zN~pxAWPi+brf4$(KUwK8NZAZri_0U=j;H)P@Ljbv`%}FcZ7FA9|8oO>fxl!7jnX(h z)h#tWKK!*{nc7f~l`1Qd%1o5#Z<)x)V5JvBsO(imZNwvXL04%dD#KZ5_nDP_R+@Yi zs()|bAMlS%Q8ucA4Q@Aa;F~yU<%9gsTpjB$AO6MOm#pqELvhQ8e|27m)T`Pb{=3?0 z{fA(ud$NoNj`zuNJ?S+BYxqCGSKRVDV7bCvrf1soPGjqyzdNzdJw7%BB1~9q zyIUKZJA0dNkL_+$9rOt9o`!mr+dtVr6k*A$PJ3x)6?A9?vpLlbub+cGwxUk^}WH6M)kccxVx!| zzSiF9lWnZg+Cr%`&vb1J)xhnB>`((|wKa6@?raD+fcd0Fuvjl)EZ*Bgs+t~F#Jda$ zDB>ly?BlTRWx(oc@9b7`MEm1vZf;$xToty8o}0#ptj+aYT9Xyw=-I4DO~;x-`(o_z z2dr=?wkMQ`s`oCt(~}xdiEM_G)$K!!nZXo`>DJJY9^}PhuR5GuXcuNpRwBWTL2TIB zx9W=CIVV^@DgSfTf|){<-evbH0V3Hc1ee?0&Ri{V=aW;ZaBf!qs`eH%OtKPndw+h^ z6iUa(r^hbIqt7bM(Nz@>buTjFIryxVd~sn(G)N-r;EhHEMn!TA-Ai2fcJno zeAr4v=E$c7ZIhF-uqwvKBF=S}67+6E_Dk>VQn^>X-DgNt$^5{WL(h!NJtTWj4SdLu zKIxw${iOV?>Uh);lYC0#arJi0kcj5`gnE0@kg)#tdG+=ML-y%!RA8gi?Cd#+rb zmlwS9B|~16mzZ#J9vF=uvJRMa0qy3 zph8`Y(F2_rgxmTOwzFzi ztXx&$DSjXF9*R$?@zTNn<)i~{#7uO{r}(tS9xa`EZqn)5l^nCwg{dArOWl<6R7dqG z89aJMpFN}O#6s1KpmhYF^6wo%_jB-^ zI`Q%QwZai6P_nV~6s25(12~LZ5JO70#d@`yF`JUzOo?ydImWG&zn6I3MjeMp5y2Li zJSXfUZ9gfauy|~h!XP=sFpRiHXeZI#f>jbE8eX-|ELKOeSRKt`bu^3BQ3oqhsOwvl zNEfMVQ1UVVdA;y>u~z?m2+lGV@NSP4diOp~1u(5s7R`e@e$Z;;~ zRVw;5D*6N!{W=x>1{M7#75x?!eUgfPo9casw>j?;!Bgychfil+xSh%>`kJhwZljAimtL1|dv zO;wr~FCq;q$Z^vA(O7AoC@2l9QHOLZkx|$fD{QOzlM(!x3byWueat0@k%h&O0jYq3 zg+=fiPzm*mKkff zduL^O=bn~%lz&He@oAYw?+KQ$Oj0ikgWaCfa%qqy(;2xuGrV$A!`xFiPQ!T&)_HZncmIr-mRJ5CUkKH|E z0}1K9chX5hdNqlVoj^z>A*7H_dJpNnCnW#uu5@b^`%u1owr+3d-n@DBfA7tG4KK_hM%g|T>lWUCF_bq5hG9WM^OhNOIr6U^1QV>F*oq z=^aQ3EKkkdpNR2@Q*|s=;+#Rw(($@&$Du6N;T>|+EXbT9S*D{&kt`2L`i#8H&Cn@= z;Y*M?Bt=M zBVE_D3qARwH6&eHrlBaEQQOG}Z`;~Zwlfy@N;$(Cv*YTc_I#%IP0+%nEB^@^=y`BQ)JiRSdc5B*m z%)(fry(fkXuv)`~I@-`KaGKIQP`NwMUpjQKX9sI#{T08S_6WxyP<+3w(Xkfm1T-F< zG7AR;I@{VSGK(WeExMTYb>m%zYi5TI7o}oBzHw~Ouu;cFxL9CoB^Ftb8w0-l8+bU zP3wB4Oopb8cNW|mq(eP6A)#XnwhGiJB7v@`V}jF9$Ra9iX!Rx7jw>~E>gYmu=*3>? zjoZ0MMs`$?ks%4a>nG(b9+bWcNgY=y7u3_czO*qOzEejJb}`z_!a@50(|^}IN|kLK zihXUw?BUV^%B6JlD$QB~3<)tM0wu}e&eWdHp`?oEejNk2T3{)|*6>Qqw;+0F<-qib z%z-q9H0;qajJ*QO%5pMsdR>xy-oxl>$ zW=eVT5OcA&Evou-GFFr#0gm|@60%D)5yVGyJPwAyDfG&KBfIT(;#(>VoczQO0qA)vD3$ICG$lBdhkQ?`jTO}0(V3MC3MN$uvn~V9_hY$ zbe|_8HJFU9a+vsOpo-!F9hRzy%jN{AN|J)YMOz>jRXIrbXgCBbj~p=fn%;P?oij)2 zF_!^(y}i~84LHvb24kOnkn>- zcY6VoL<4TXAq|Ih+=!b5PW6qZDq=iks_I!~GpAak2ANLFAP8nisnFvERvdq1*3L3A}p!n&+V+0G4@26b8G#fUq;;#@{enD)@yi&MbCId9rK3 zv+!&U&(ZN*JWt@vvZ;<^PB3D-kuW3KB8uCcg;}tYX;IIbVidSiP zwT{=|wF28J3D$*Kvo$qxIf2n=Fojx0d^;0f|J!Nw)~$HGjyK>of!d6+5OHzQ_945Q z@g^N_#_d7hq{2+#Tr!+D;=3%i4h*v@j3|%2O~>2u4z@LcdHPD0C2(8R5Yx!IIIR=^ z9~`a6yErH?%2cD>*4~n{rQ1@ly_S+ITe3mB-(va6?XIuKdju{SR&}_=ku2*R0a`ML zNjGPE-te;HE%H#2y`;>oXQ$Oopde%u(`4At8ySl$O({ETSi^>6s`sH_vBn!W2@z|9 zxul{oAi-?$I1c#pg{dG=pn0%V@XWj%HeHjtmBa?>|OsOKR;coVj zH7P}9E1JQgfSL? zi&M%tX4c1;t86D-%H&P|E`w%l?6Pgo^&F!Z^lfe0Zt%%9s%9Jf*3Rz%4w z|1mi7#CxNINXWU{u&gwT2R*3w6nM4dcdn8M{&#`Ri>via%&=M0@GpT2=2&(@LAh&C&c^tr3&xkr}`OK0kxtB1UP~_ z_$KfH{#xa4-o!UWryYSdiBrnk)ujbEh}WSd!a@sKe2~AX115cTcP_xLaW=bF5?*jp zc2f(mJ8d?*b`o}+l-*Gpq1sn=DPTE8+n-_o5CwTG93s)Ymy#Ek1{sTrknpRHY+$}4n z(Aw)evtttLkKmFiT+w#~+ty8D$GV!kP_@5$ZF&-qzM|#`b~o2>wYjF6%WA2%xpoSD zo9oD9@bo%9t%t%v$t%tRUF)b%XxN!;k6Yju?-t>C3f&KZ8tw9lD>*N z1L=GdGR!c7bMQ&pO2;+$6z-)KE3u0=d-u{u8+pz5X@0BW{#E!4ztxi03f#vXbrJIm ze0C;8Zuh?d-PCbLZR$C`zxoI!CZViAee?IAI0+{;Lo$VfO*bHt-|HsZhTFj7`iwfpfoD))JsM&(?v@&$g2BuryW z;WO8i`);Dz)qJ*h9L4hmQd4+w)63T!#Ve~R)9ZNW#q~F`t3HOeC=a|f;(@a%9&j~n zI*79{gl6nPE1zxH?+e!wFvgegWzuQ1=vVMn9(xv+;cNIhswfESLMX^OJ{1sDH@#D# zM-)T$`s@M>sm3?)Er45DkLGNB_w21Z=5D2TzvCb9-5H~NkMG~-pOW}@{QCiZgrEA~ heukgpSK->Px%O95srl_z{0;x8TY`V$-}n!j{|k(ol4}3} literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/ConvertNumberToPeanoExpressionTest.class b/solution/H07/build/classes/java/graderPrivate/h07/ConvertNumberToPeanoExpressionTest.class new file mode 100644 index 0000000000000000000000000000000000000000..c89acfec08894836e91eab012df0d8fa40dbef21 GIT binary patch literal 1079 zcmaizTW=CU7>3^g+7;N+a%fAn^-#5?cvur-yufG>Y0`uO0VLj$0j4kryJU80^k?Zs zO}y|2_@j*9ENe@uhTUX#XXl;gduB5G^Vjzu0E&1LLkM955fdv|W!M<;b8d~fJ+Nxs zk?460tFNRjz1Ixk+)+D<8;BZ+nTW$=NDZI8v`S;{x(#tAl(2h(VZT(Xw#$uHr~3Z% zZMo5D)jIWZv0CetKhzuLX7i+0Wyn+pA-W}7IRK@A>ahoft`>pxMh&PljLvFsWOYsGUghyq3Q|VDrhMmUD_T)sg zr7H7QhaIQinb`_aE@K559RFoTPY)!0Dynqf79Mz}WDOZ(Skv-wte3FuQ;= R{^1!yo{}Lv!XNv`z;Eab?85*6 literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/ConvertPeanoToNumberExpressionImplTest.class b/solution/H07/build/classes/java/graderPrivate/h07/ConvertPeanoToNumberExpressionImplTest.class new file mode 100644 index 0000000000000000000000000000000000000000..42c644bf6d08fdefac79addfa1bb5bf7ba269b7c GIT binary patch literal 6798 zcmcIp2Y4LC75+yjX{FPGg)qgKayY`4WZ7q`0ogK=e2xUCf=-t05F%E0D{1As-D7vp z1=2_(4bpoh2`Qw3NQCSJV$wrMZ={EG(t8idKf9~DwNA1R<;(ZkJGZlM-n{z1H=_q0 zJ$xU4F3}i86(S0%Rn(wXpmAE;r^U0HIT;@upVrf^K9{-LD6%4GTajwrV{QN;==&Z*?A+is6#+mt1HaJxQXn0iK%oTQ>jlC1Pe2DF@> zDbh)Tl`2k=1ZVjK!O}i6AR5xrd$mbDiqmkqf>kQcz-oauPaw*KnA6Uv0x5@sDs zjCLh=c8w(H8!rVGtfahE=v1*y8mEqS_r!>D%Ptk&=%H^7bDy=B$#!MAv?1*SVXrBl zT0|vjq=bqccsy;fe@Zt6E)R1LnEAe+x1Qq`#>W{@@j-La;+P8FsX`yFRB)AwB>Dpb z`Ki?7rV~iaf3tsCO;; z+tm*chx%K>fjAFD6+wxQ;U1C%>^hoQz#J7W3XCJ>$dIk~Sh<`o5ie08LWS6tmZu8& zeAe*%z8?n^98_@wZe%i4f>I%lU0&^yGG8E|`X3V47qqM+aCbP2g2XCM(&d`wv94Q0 z_eJ7X!BYfQlp?DLN>7s&;^_jJuu^_*gdOhBJoeJD%W$Xqt&A~2pEwM_X9#So#1*BY z5R@MuWn}@1;wC&x#k27odPd@_o5<>Z=&WVvIC+ajI#?gi=;aEH(OagijLyB1T5dd}Me$<1 zM8Qi{ybLdA*C9(y@21Uu*C8XnC_Mw~+F;9~C>^1&@;$IXy6!rHWVK)ht0;I<4oa>N)cT*IO`AFujr=XP!ER9N9JCwRoL^*QwhAK z@5kFz+>W=?S!o}Ux(kNXSAu$FQ5j0^0EL%&Oo>j~!BR7$0IS_sug<$Yup@3mak{JC~<*$NvW@>u@iRL5wna zjA&_%Wh~u^nU)(XIC?DYA7)}%FS(tKb@+(DMP5CQ*kuT@##X|;PED|<&C%mEAom;UOcL?Q6!Mb zm*5x{Y?F}fhvw>IyO~URc|ao1%ABDP-NjiDGpqdAlgRUot(*8rz z{!_&d@Ngp@=ES3N;y)^Wjz?D13K11mBBF?DRn&-Dfi)!$`DgsNAFtF#o6yp{N@D$N z$c5h?3>U;;k*|EOW@fUw)10)dy@hnx+_RRKgC!P9z~YnqCO7z$$L`Zhuxnh%ZY>Gd9hco_mSA`CLU!v(*nV7g z4`4MSp0ZmhvDB(&{TxnR$n1Pn^Xf*bda6$ps7i8t77udi=lHFf3d?rq*;iHZ8(|aOKSuQXS!v^NCZ&%5<8yT(O#ifF+Scy)Y&YQ*< z$93q!CiLJ6Z0BX!4w&d=``+i7rPJ5QGdn{QH#3aCPW!Ip<;XYi5H-I71H2=9h<@FP z%kWM9swRgRzD2s4kfQ{?T@0q%y7TqOQZyQscc~@izIWnx#<>~ z^F@d83g8f4Q^gYtxb^*fuHmgU&`;Kb{1dhJFPxk~dwU!Ef z2j8Vi-{WeTo&L=C`Af!DkXrnU36Y$0M>uyQcZ_gsZ99ZF2_)z6)~0u?KZJKhDAW6S zNAnJ<BDz&2&2t49y=dxBKQS<32-SZSJ~407B1~AUrL|;+S}ka zMWg(d@4w@JN=y+V_&xrJzj(j?iofGu!Q8(&r;tjX?d}kDB3fH78pH`=1y=nRQ8L(Y literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/ConvertPeanoToNumberExpressionTest.class b/solution/H07/build/classes/java/graderPrivate/h07/ConvertPeanoToNumberExpressionTest.class new file mode 100644 index 0000000000000000000000000000000000000000..6212fb3bb3a805a1b29cbe744aec95bc2f39efad GIT binary patch literal 1079 zcmaizTW=CU7>3^g+7;N+a%fAn^-#5?cvur-yufG>Y0`uO0VLj$0j4kryJU80^k?Zs zO}y|2_@j*9ENe@uhTUX#XXl;gduB5G^Vjzu0E&1LLkM955fdv|W!M<;b8d~fJ+Nxs zk?460tFNRjz1Ixk+)+D<8;BZ+nTW$=NDZI8v`S;{x(#tAl(2h(VZT(Xw#$uHr(P~r zYn@iDQ+w%q8HKhzuLX7i+0Wyn-{p~|18O1Q3c?3Qq8<0B=f zPusa(p>@v_E#4i|msG{+@o}3gsr$jlh&PljLvFsWOYsGUghyq3Q|VDrhMmUD_T)sg zr7H7QhaIQinb`_aE@K559RFoTPY)!0Dynqf79Mz}WDOZ(Skv-wte3FuQ;= R{^1!yo{}Lv!XNv`z;EUp?85*6 literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/H07Test$1.class b/solution/H07/build/classes/java/graderPrivate/h07/H07Test$1.class new file mode 100644 index 0000000000000000000000000000000000000000..76b642f981dc58e919cb7a072c0f8d0c78ad6c8f GIT binary patch literal 1637 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 JNwcBfe*udq4}1Us literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/MethodReference.class b/solution/H07/build/classes/java/graderPrivate/h07/MethodReference.class new file mode 100644 index 0000000000000000000000000000000000000000..2c05b6bc94eb6b3b6541afba23644c4fc5a7a133 GIT binary patch literal 23733 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 Iim34a01^3K)c^nh literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/NumberConverter.class b/solution/H07/build/classes/java/graderPrivate/h07/NumberConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..2053819ab008fbd613e901cb8f981eb482fb186a GIT binary patch literal 2827 zcmbtW*>@9F82{a*?X+Q9+ENOXB0D4vGAt@eKn)>iFilF5RtjpJPH&T;)0r@twBWwr zzAt})FTVJIeJH3$efPe+nNaHC98XT>&i(GU{=VhTZ-4*z3xG7fjv<1m zgbo><=wj%wO46NLZAqEK9VHsPnl|iz3-B2~oa5f&Y zlBub7nO|*kQ{$=i==X4|2P4=nVN}KrJistmJ90wF7;2+Y;`7`V+88=6WlKd0E5G)T z!WzLY8N0EET&r>?ubT@DX+prVtBTW{Q;n*nh)2`WjRsL1%T}t~w`-eb_JIfQ*BPGo1ck+8APiC5BCH`EjF7Nf=|;7-Y?*#*n}v84uzx zLmvf~AwM0vsZj_F$K#j7I19{DVSs&$N=S&JI)bATj>$NVhZuGQ_U^&Wu)*ZZIWnob zX*k$s&@0F`i#|!D^br{+L_T}UlbKAmTrQRb^)VSI1+}k`u1uEF`I*Ax_?c`;!YPJb zfiIp(M^{B+vez_T7cUa1>URcQ1*_cDYUA9gS#u$#CmE6f)19z#=8~nk`YNhTNQMN? zwA(feUR8~>rtwB2#C4WoBv4ywnvTB6Tjw!ka85MsQw&?fZBeP&*0MTl@Kj<-Adr)B zULY{wMLv_gI8h>aa>YUnd5lXa$S7ihYD5&=qNOe9j-`xyD|LdPFzgST@aiX=`BolE zC`+iwn8Xxm6y4*&RSJ4*WQ`*;*{O7XGF{0sY<4^DE*UDK2rkN)7Jbnzs#26*3?*Ea z@f@C~8Ko223)Hyh*ZLVMS>MfY6|Y}Z0-hNeFG3|0mTTN(I2qR7k__Y4aGJBTG!m7f zS+!^_`+EvO!<+;zV;(dx2ZGGzOovxFwU@M{8cklDXBdv>!sz-OsSVI^MZ$s%LpZhX zehkwfaLD%(cbc{->cNy@iF(*Fkxdthem{h&qK9C;D#I2D+_er*D`7D>Xi8X;v5aee z!VAsCS#Hw|SmL%L;_7v*39g!!cR)FAkIu)DK+afml){ZP4Y|i#5p_%>I!~QsOsTdm z_CB%0sp*Y71#_3p6lrm+f=V%~MqqYrB_wh*a_V8{2G=st^q?Ea<_&H-ZbJ)?g8ccn z9o=0z{YfDsm&1iZweODnC0?x49ndyn$kQ&<1&nYiJF2!YuGZZMC49tiATaY^TF4;^ z*Hx3fCOmD>^r9Qr(;OznS_7mZ;d9DZV4yWPs5aU%)+S%JnzqKz=^`&fp2=3K4+~}3 zO*Ijrj|&B-eNQhDyhKlN47%-KcAqW-Ucsxh>%nVy-4`yP z!&N#wwhAeqT*Zdu;K1OfRcxl$x$lVE(;V0B_-K(%B;l z*4O<9(W7*FndMioZ52CLu{ZiN601nk5?O_kkDeYK`36T<@UVB>LC4e46+G%~%fw2g z$aFMGuS)(#gnj$Z@5!6vKOr-H=oYfSy6#Wl0#f9VSWo-w6aJbe7X%!8&`r-Fq7GBD zZY4CgAxCQw+evDansbL6*cfRXr91To-XY!+1@tc7qc;iz?-NY`GVO-V@B!`m5&a9J z5+dwR97{|1kR(1P2qJE7sy@8Q6+G>QbQ{kQ8W#xZXMGed-Np+ew=w$zY7rvdbWI4C z`&{()pci}T>tSCA_oVMiFCM@rlmUiMiNAx^&&d22_cFg2HeX+BzOjz^IGIn-Z|pwJ KGkoa=@YTPaPT;`+ literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/NumberExpressionFactoryTest.class b/solution/H07/build/classes/java/graderPrivate/h07/NumberExpressionFactoryTest.class new file mode 100644 index 0000000000000000000000000000000000000000..e8c3f6e6b20df4d39251346a2e622737a7d1651a GIT binary patch literal 15193 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 aJi7>7$X{oBL2K4pN=mhhwRPGCs{Ai<;HkX; literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/NumberExpressionTest.class b/solution/H07/build/classes/java/graderPrivate/h07/NumberExpressionTest.class new file mode 100644 index 0000000000000000000000000000000000000000..4d3996b5a47767a31b0536015b0fbcbb9196ec2b GIT binary patch literal 999 zcmaizTW=CU9L3K7?FuYZE^Pr@@0Ye-wuv!)z-SO@Y(lXCN_=aEWeS6^OJ*0NA4?x< z;)5T+4`uw%vbLnfxSPyn=gjY%x$LjsKYjwJ;AsL8L=D7DEMb`;IoRE^-tF$Sh37LY zzm$&jUok|twmWfLL)<{ZL=q-LRx7I`?s-jdDwJ?+!H{VjAHJzIPih~InzdHz;C+K3 zU%#p>CkU1{v7$ZKh#{0;b(IpfKl<`koJvRZ;>aLtAZH?vRfe3V914Hn_T~&rR}4>T zol5<<(ylSA2F{n}kaY%W?O!la)c*OIe}j)j?>vN76|`!@#HLnl&QxKz11D4-ar-0h z3j?(dOL|eaY5cn~yqNN!<@W#{7Zw z7)n9@MZhvc+NUE5(nz0d7>doQaOZr!zrC6l@sX;W$}r$ zbU0!qG>g_RojzRw-3gaPLoIizY_TtO*y5rr&xZUHXLuf1c!9dFcu!bE-k-UsX;(=* zFxz)kYuX*lU~9^_gPU~!^b-TqH;~HP)U&8&R4?s(2m4Bm2uTqP0|xF=+nfn-5BI6Z z@PI}m!Q|KB8P+Z!X+&v4lH?}6sX16Gggp$c9tGg7e}LBmaOpBQL-H(v pbN>ZzpMzh7iH#ufjSHmyJAri)7Upoqf}9cTkTQbD_?!L-@CWFJ&X52A literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/PeanoAddExpressionTest.class b/solution/H07/build/classes/java/graderPrivate/h07/PeanoAddExpressionTest.class new file mode 100644 index 0000000000000000000000000000000000000000..c16673882360f1358cf69a839018db16624b5010 GIT binary patch literal 6756 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 literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/PeanoNumberExpressionTest.class b/solution/H07/build/classes/java/graderPrivate/h07/PeanoNumberExpressionTest.class new file mode 100644 index 0000000000000000000000000000000000000000..b619d427289c7c7a6ec24fd27fa42276b987dde9 GIT binary patch literal 1031 zcmaizTW=CU9L3K7?FwvZxwNI)oAd(u4v5N_-;&Okogq$?RhEW9dUp zeDDMKp^X1o)|OO>yUEPX&iVh&nc3N&zrOzfP{fl2B8VD@nOMRy!`hI48hzY}V{zrP{8XoxZi} zZTo$#ZZ{ey)e1wd{I|Z4AY{tKs4;t&X=Ds!P2{l7kkyn^ z;Sb#2obCPs+qT^*md}b!n_)fhzg9^B(n#qPc@tYYMQ)a&!pEX_8AYq|TD5IrN2_*b zsxab-6Dn)G`+@g`fjyGwpf$lAw=x}fgt9+Pl<++1I!)ox*2YS1k2Y+zOpBZ;n!Gcj zH<_~A<)ao?Qjf!zF@GREhP_}B3#kQ$luz^^m-NYtVXHoMd^r{^=}F=h9mn;#o+8|K z*;RdOIHhk)?L_)QS$rZbosd`w&7z%7cz0o-r}{`SJP&-l zpro&OPgq0VpINDCN6BvBclR9Bd_oJqWEH z2H=AQ;LQMh^Ex<9@(h8q{{83A)=6M z&&(AYrssP}#1Pkz(4pak!tm>b%xq>>A>p?zFEhi1THi`Zyiz)bpev*v8Ft3mcxX0# zg&Q@;Z593QreU|7qP)7kWqX|Q9kvy{R+7}1c{ zF^VyT^h4v3QM8Rtt9Unzomj9smcOVF&F0pJFpg6iCUm@u(+YEMnU)oL0StxlY_9eu zX%8F=J&X4=yszUN&MOS{kq}nC?>=_aIfaY(K*J>+A0nf0`FM=3xn+~PK#u!D76W_M zwq+Zx zl>`eC`%{GyCHen&51*$PZs}M;na4fM(Qp*5X9oxwP*BQM6{^_-7hr%G2Vv#b6=KWI zChHxkSsin&yS-t$4Y>jeV>PE~*y|Kt{)dw>xq`C0@9bq}OC)pE^xMwnJ;OD&P2Y66 zX}Ini%^z2dozOQ~w^|*;?+U$%Y_3sn&@b-zZPQhl9iWIF5kwLA*87g<#6irDclL45 z4H|wy;4Kp1&4DEfT}7x<{nsTtg@J&5cP5;EYk;Y`({-EXiY20@fL-D%p6 z$G+ARN5{ALj+6&?NWmVYvO@=FP_!iS#2Q=t9miv1)~g-%-eueHJkw)eim}})UgIdz z(lUT_TH1MF`6XcENbom`&k(^fM_b$(rJc$bb`i}_?;@Fhj^TX%8Imt?Qh|f$Gn{#W z3%i*7gF7Rr@IA&%zy!0M#z~yPB<<~BCc^g=R`5Bkj3leV9gdS+`Y9biQPQivE<(@bqBTH2u;)uUv9p9h_6SU>EEirPukZxv{2pe0*+(aTo**81%4L31Ut#IT zVGoN^P(P#n0g@qbQ9Mo!D0n=CR7WFlypMI-7{9^a;6X5>@ICDqgPx_8M~LV1AH-!B A^8f$< literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/graderPrivate/h07/Tests$1.class b/solution/H07/build/classes/java/graderPrivate/h07/Tests$1.class new file mode 100644 index 0000000000000000000000000000000000000000..329655a7579f86a0e300d7311a978018c15dcd7e GIT binary patch literal 1428 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 Lq}8|Js37$Ziq8@Z literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/main/h07/NumberExpressionFactory.class b/solution/H07/build/classes/java/main/h07/NumberExpressionFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..010685c08342cf99201618604775a613f790a467 GIT binary patch literal 302 zcmaJ+yKcfj5S%qO2J^DgCKTxcMVyWTgcL3rzW|;Q25?aE;Wpu+N(h%?Euu{1pV3>glxaz*j#RG7F`@F%oBOB{ zZWm93=ymm#NHf`d8(9=e=TniE+H48#i~f*=PONfyYI+w*#>!2sQ<2SuQI?-Yw_K=# z(2cLm91?<=UYS%*l^t|2 NacnUov>6?A{sB|8L}vg1 literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/main/h07/peano/NaturalNumber.class b/solution/H07/build/classes/java/main/h07/peano/NaturalNumber.class new file mode 100644 index 0000000000000000000000000000000000000000..0b93486c1d257dd9916780664d504b1f3dcfcfa2 GIT binary patch literal 424 zcmZ{g!Ak-`6vn@&t7~RyCPZ}VrX89t(ZL9$2!h2R#rwDp>&QA2yEFb@oq`Vi0sT?Y z+ck;~&Efla-}^D|@jgD^-T{ozYodZ`h@gcU>V(cpZlp-1NyOuPrD8{@Uu&b?4WZf} z%tAB>N6U*V@vNk=Vl17{WIFcixylH^tz9TWJJLpNv#Fe?oOB}_%XB6)UDV%U;FdZk z97q5BHzYKiow!V!gwX2`qTlVdDHF|!^;xX$bvfqGKIa8aIC=8M>9u+=8=Y$&KQhKT z>9jRG{W7vyBAj2yG_j%(?{u1roFiqNkUy}vvt#R~*2l|XaEg#GSG)?SxE<>bSAw0` lYiF;Zm$KbtE!tpUm$kJ8*!O^du#a}hbxJ)zm%ZQ*fiEb?XBPkf literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/main/h07/peano/PeanoNumberExpressionFactory.class b/solution/H07/build/classes/java/main/h07/peano/PeanoNumberExpressionFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..635524c215458144a96ba61e5c9a05dbb722f765 GIT binary patch literal 329 zcma)1!A`Mq$9qo3u8#DgE;M-gYi zvtcHAGw;o0GVkZ`^$p+wodf}DF~Sxi)Crx9e3PP(=0(i1jmj%R{azbgjS02E^(sb# z&|lvT#a2mU#oXi5?ln_x^1gMdEVVULnOD|*5W+|MtO)H?8+BS*%B*0eo7!9!E9tc7 ze_~jzbx9bc=baxBl7-#5TursV+57L8Tki`!#BA3Gak62?CNpv5KyPfc7tyJx<*K literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/main/h07/peano/Successor.class b/solution/H07/build/classes/java/main/h07/peano/Successor.class new file mode 100644 index 0000000000000000000000000000000000000000..e21add3cfa91ce99f918fcea4774bac23f3b3d00 GIT binary patch literal 1054 zcmaJ=-A)rh6#k}^ZYc}J@+X2Q3fLB9y)j(Wm|#sKNiB&bc;VHsowNhXOtUjf!khRQ zn)s7&;RET>Cf-CK{ zxQ#*{w4(D95i;anN+sRMdFtcxP%81h!PZ75ZjVWC`Up7IOs1zdH##9J#-)g>46SfE-sqOLM>_I*bmrV^t*x;k@4pkar#mK(4Qi`hW|d+Nj|dA~7+_yTsWcV~b-4vM6zvZeE2(#JL`Yh_#ZeGHe=UU>?WnbI^ z|2T#}JUJDS%Q(3VzEzwUujBCH487-1Y#8MbcpbX%zoo-(ZeA4*>!=?fe5 z`ZM$p8ScdIpR^3=lUO9VL{@|BI9{m!0ITkNgY#v8StdD)36d_dn86fTcgb2x&{)Ae zvM6uB%7~5rM9R5GJEPc4^(&n3n7N{}@tGVM#I(6Vur#1^6JSc0#p(dHhWjaQo%RQ` U@`QUt>mkZy6-cXK2hXtb2Vh1G0RR91 literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/main/h07/peano/Zero.class b/solution/H07/build/classes/java/main/h07/peano/Zero.class new file mode 100644 index 0000000000000000000000000000000000000000..dc032008fb4841d8dd2a93555b72946599a72a51 GIT binary patch literal 462 zcmY*VO-}+b6rAqz?Fx#h2T$I>MC-+Pz?cw?iOGh85Dwf5G)v9Wn%$P)r6&^){s4cJ z@fGl^hnc*2Gw-GE91GpeA%z{X|N80x=~vCIrZ;l|7)LnBsNuG2#?Nl9tOW-8K=$ds=)V!_T;&ae~z zAJb*1STnGh(g{PW-H9K?Qt(vhgs)X{)CR_7Q+cQS^s3)}=3NX&4^CUPkoS72az)E} zS{o~@GMaW>#3oC)bu*DBhI?>Ur8&<@lG<|dW9GM}Z|u;x>AZ_$ROwj$1z`SMgj-Z` zVn$p%c?Ek}wIf2`21T|BqqPBbG^nEAVwcc|Pl>%RY?hyi0xOiZU literal 0 HcmV?d00001 diff --git a/solution/H07/build/classes/java/test/h07/ExampleJUnitTest.class b/solution/H07/build/classes/java/test/h07/ExampleJUnitTest.class new file mode 100644 index 0000000000000000000000000000000000000000..774183bec62551264b0c7bddf7d978262f3b7a60 GIT binary patch literal 504 zcmZvZ!AiqG6h-f(O`W2?|=XpSD9gB~5BF5r4~-;=&K` zqr^9{ph&a0!<##E-kq1vulElCK3Wb8lx&n;n6MaXGycTAh{qG}b~qCw#bBMwSgH$# zQo9p6Si`yv$HfL*hJz%Xc(a^*(uGta_4q=1ewK+;$t2DgTwWBt$DBu0n(cnS6WXXS z>`aeOz1}mQFCuaMK#YONs9*Uq84HGLAY*Zp&xax%@L@zd^&lDXDCDWs^>VYUrjoGD zU={3)+AD(kJAy`X7gFMY|7PMVb1AE^p`)e}* literal 0 HcmV?d00001 diff --git a/solution/H07/build/resources/jagr/graderPrivate/grader-info.json b/solution/H07/build/resources/jagr/graderPrivate/grader-info.json new file mode 100644 index 0000000..c142ecb --- /dev/null +++ b/solution/H07/build/resources/jagr/graderPrivate/grader-info.json @@ -0,0 +1 @@ +{"assignmentId":"h07","jagrVersion":"0.10.3","sourceSets":[{"name":"grader","files":{"resources":["h07/NumberExpressionFactory_filter_true.json","h07/ConvertNumberToPeanoExpressionImpl_0.json","h07/PeanoMultiplyExpression_X0.json","h07/PeanoNumberExpressionFactory_filled.json","h07/NumberExpressionFactory_filter_false.json","h07/ConvertNumberToPeanoExpressionImpl_X.json","h07/NumberExpressionFactory_filter_complex.json","h07/NumberExpressionFactory_multiply_Complex.json","h07/PeanoAddExpression_0X.json","h07/PeanoMultiplyExpression_XY.json","h07/NumberExpressionFactory_multiply_Simple.json","h07/PeanoNumberExpressionFactory_fromNumber.json","h07/PeanoMultiplyExpression_0X.json","h07/PeanoAddExpression_X0.json","h07/PeanoNumberExpressionFactory_empty.json","h07/NumberExpressionFactory_filter_empty.json","h07/ConvertPeanoToNumberExpressionImpl_0.json","h07/ConvertPeanoToNumberExpressionImpl_X.json","h07/PeanoAddExpression_XY.json"],"java":["h07/ConvertPeanoToNumberExpressionTest.java","h07/ArithmeticExpressionTest.java","h07/ConvertNumberToPeanoExpressionTest.java","h07/PeanoMultiplyExpressionTest.java","h07/MethodReference.java","h07/ClassReference.java","h07/PeanoNumberExpressionFactoryTest.java","h07/PeanoNumberExpressionTest.java","h07/PeanoArithmeticExpressionTest.java","h07/H07Test.java","h07/Tests.java","h07/PeanoAddExpressionTest.java","h07/NumberExpressionFactoryTest.java","h07/ConvertNumberToPeanoExpressionImplTest.java","h07/NumberExpressionTest.java","h07/NumberConverter.java","h07/H07_RubricProvider.java","h07/ConvertPeanoToNumberExpressionImplTest.java"]}},{"name":"main","files":{"java":["h07/NumberExpressionFactory.java","h07/peano/Successor.java","h07/peano/Zero.java","h07/peano/NaturalNumber.java","h07/peano/PeanoNumberExpressionFactory.java","h07/Main.java"]}},{"name":"test","files":{"java":["h07/ExampleJUnitTest.java"]}}],"dependencyConfigurations":{"graderImplementation":["org.tudalgo:algoutils-tutor:0.7.2","org.junit-pioneer:junit-pioneer:2.3.0","org.sourcegrade:jagr-launcher:0.10.3"],"implementation":["org.tudalgo:algoutils-student:0.7.2","org.jetbrains:annotations:26.0.0"],"testImplementation":["org.junit.jupiter:junit-jupiter:5.11.2"]},"repositoryConfigurations":[{"name":"maven","url":"https://s01.oss.sonatype.org/content/repositories/snapshots"},{"name":"maven2","url":"https://jitpack.io"},{"name":"MavenRepo","url":"https://repo.maven.apache.org/maven2/"}],"name":"FOP-2425-H07-Private","rubricProviderName":"h07.H07_RubricProvider"} \ No newline at end of file diff --git a/solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.html b/solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.html new file mode 100644 index 0000000..ff0de73 --- /dev/null +++ b/solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.html @@ -0,0 +1 @@ +

H07 | Peano Arithmetik
KriteriumMöglichErzieltKommentar
H7.1 | Interfaces definieren[0, 4]0
H7.1.1 | NumberExpression[0, 2]0
1 Das Interface NumberExpression wurde korrekt erstellt.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
2 Das Interface PeanoNumberExpression wurde korrekt erstellt.[0, 1]0Kind does not match expected kind. {
expected package = h07.peano,
expected kind = INTERFACE,
expected name = PeanoNumberExpression,
expected modifier = ,
package = h07.peano,
kind = CLASS,
name = PeanoNumberExpressionFactory
}
expected <INTERFACE>
actual <CLASS>
H7.1.2 | ArithmeticExpression[0, 2]0
3 Das Interface ArithmeticExpression wurde korrekt erstellt.[0, 1]0Could not find Type ArithmeticExpression. Type is not defined or could not be found.
expected <true>
actual <false>
4 Das Interface PeanoArithmeticExpression wurde korrekt erstellt.[0, 1]0Could not find Type PeanoArithmeticExpression. Type is not defined or could not be found.
expected <true>
actual <false>
5 Alle Klassen und Methoden wurden korrekt benannt.[-1, 0]-1NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.NumberExpressionTest.testNaming(NumberExpressionTest.java:18)
6 Alle Klassen wurden im korrekten package definiert.[-1, 0]-1Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
H7.2 | Multiplikationstabelle[0, 3]0
H7.2.1 | Multiplikationstabelle[0, 3]0
7 Für ArithmeticExpression wurden nur Lambda-Ausdrücke in Standardform und für NumberExpression nur Lambda-Ausdrücke in Kurzform verwendet.[0, 1]0NoSuchElementException: No value present @ java.base/java.util.Optional.get(Optional.java:143)
8 Die Multiplikationstabelle gibt für lowerBound = upperBound die korrekten Werte aus.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 4 more failing tests
9 Die Multiplikationstabelle gibt für komplexere lowerBound und upperBound Werte die korrekten Werte aus.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 5 more failing tests
H7.3 | Peano Arithmetik[0, 10]0
H7.3.1 | PeanoAddExpression[0, 5]0
10 Die Klasse PeanoAddExpression wurde korrekt erstellt.[0, 1]0Could not find Type PeanoAddExpression. Type is not defined or could not be found.
expected <true>
actual <false>
11 Die Methode evaluate gibt für X + 0 das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
12 Die Methode evaluate gibt für 0 + X das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
13 Die Methode evaluate gibt für X + Y das korrekte Ergebnis zurück.[0, 2]0Could not initialize class h07.MethodReference

there are 7 more failing tests
14 Verbindliche Anforderung nicht erfüllt[-2, 0]-2NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.PeanoAddExpressionTest.testEvaluateRequirements(PeanoAddExpressionTest.java:87)
H7.3.2 | PeanoMultiplyExpression[0, 5]0
15 Die Klasse PeanoMultiplyExpression wurde korrekt erstellt.[0, 1]0Could not find Type PeanoMultiplyExpression. Type is not defined or could not be found.
expected <true>
actual <false>
16 Die Methode evaluate gibt für X * 0 das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
17 Die Methode evaluate gibt für 0 * X das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
18 Die Methode evaluate gibt für X * Y das korrekte Ergebnis zurück.[0, 2]0Could not initialize class h07.MethodReference

there are 7 more failing tests
19 Verbindliche Anforderung nicht erfüllt[-2, 0]-2NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.PeanoMultiplyExpressionTest.testEvaluateRequirements(PeanoMultiplyExpressionTest.java:87)
20 Alle Klassen und Methoden wurden korrekt benannt.[-1, 0]0
21 Alle Klassen wurden im korrekten package definiert.[-1, 0]-1Could not find Type PeanoAddExpression. Type is not defined or could not be found.
expected <true>
actual <false>
H7.4 | Funktionen höherer Ordnung[0, 15]0
H7.4.1 | Interfaces für Map erstellen[0, 2]0
22 Das Interface ConvertNumberToPeanoExpression wurde korrekt erstellt.[0, 1]0Could not find Type ConvertNumberToPeanoExpression. Type is not defined or could not be found.
expected <true>
actual <false>
23 Das Interface ConvertPeanoToNumberExpression wurde korrekt erstellt.[0, 1]0Could not find Type ConvertPeanoToNumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
H7.4.2 | Conversions Implementieren[0, 7]0
24 Die Klasse ConvertNumberToPeanoExpressionImpl wurde korrekt erstellt.[0, 1]0Could not find Type ConvertNumberToPeanoExpressionImpl. Type is not defined or could not be found.
expected <true>
actual <false>
25 Die Methode convert von ConvertNumberToPeanoExpressionImpl gibt für 0 das korrekte Ergebnis zurück.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
26 Die Methode convert von ConvertNumberToPeanoExpressionImpl gibt für X das korrekte Ergebnis zurück.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 7 more failing tests
27 Die Klasse ConvertPeanoToNumberExpressionImpl wurde korrekt erstellt.[0, 1]0Could not find Type ConvertPeanoToNumberExpressionImpl. Type is not defined or could not be found.
expected <true>
actual <false>
28 Die Methode convert von ConvertPeanoToNumberExpressionImpl gibt für 0 das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference
29 Die Methode convert von ConvertPeanoToNumberExpressionImpl gibt für X das korrekte Ergebnis zurück.[0, 2]0Could not initialize class h07.MethodReference

there are 7 more failing tests
H7.4.3 | Von Zahlen zu Peano-Zahlen[0, 1]0
30 Die Methode fromNumberExpressions in PeanoNumberExpressionFactory wandelt einen Array von NumberExpressions korrekt um.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 4 more failing tests
H7.4.4 | Filter[0, 3]0
31 Filter gibt für ein leeres Array ein leeres Array zurück.[0, 1]0Could not find method NumberExpressionFactory.filter()
32 Filter gibt für ein Predicate, das immer true ist, das gesamte Array zurück und für ein Predicate, das immer false ist, ein leeres Array.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 3 more failing tests
33 Filter gibt für ein Predicate, welches nur durch vier teilbare Zahlen akzeptiert, nur die durch drei teilbaren Zahlen zurück.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 6 more failing tests
H7.4.5 | Fold[0, 2]0
34 Fold gibt für ein leeres Array das Initial zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 2 more failing tests
35 Fold gibt für ein Array mit mehreren Elementen das korrekte Ergebnis zurück.[0, 1]0java.lang.NoClassDefFoundError: Could not initialize class h07.MethodReference

there are 3 more failing tests
36 Alle Klassen und Methoden wurden korrekt benannt.[-1, 0]-1NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.ConvertNumberToPeanoExpressionTest.testNaming(ConvertNumberToPeanoExpressionTest.java:18)
37 Alle Klassen wurden im korrekten package definiert.[-1, 0]-1Could not find Type ConvertNumberToPeanoExpression. Type is not defined or could not be found.
expected <true>
actual <false>
Gesamt[0, 32]0
\ No newline at end of file diff --git a/solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.json b/solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.json new file mode 100644 index 0000000..a8ef3a2 --- /dev/null +++ b/solution/H07/build/resources/jagr/graderPrivate/rubric/h07_ab12cdef_sol_last_sol_first.json @@ -0,0 +1 @@ +{"submissionInfo":{"assignmentId":"h07","jagrVersion":"0.10.3","sourceSets":[{"name":"main","files":{"java":["h07/NumberExpressionFactory.java","h07/peano/Successor.java","h07/peano/Zero.java","h07/peano/NaturalNumber.java","h07/peano/PeanoNumberExpressionFactory.java","h07/Main.java"]}},{"name":"test","files":{"java":["h07/ExampleJUnitTest.java"]}}],"dependencyConfigurations":{"implementation":["org.tudalgo:algoutils-student:0.7.2","org.jetbrains:annotations:26.0.0"],"testImplementation":["org.junit.jupiter:junit-jupiter:5.11.2"]},"repositoryConfigurations":[{"name":"maven","url":"https://s01.oss.sonatype.org/content/repositories/snapshots"},{"name":"maven2","url":"https://jitpack.io"},{"name":"MavenRepo","url":"https://repo.maven.apache.org/maven2/"}],"studentId":"ab12cdef","firstName":"sol_first","lastName":"sol_last"},"totalPoints":0,"feedbackComment":"
H07 | Peano Arithmetik
KriteriumMöglichErzieltKommentar
H7.1 | Interfaces definieren[0, 4]0
H7.1.1 | NumberExpression[0, 2]0
1 Das Interface NumberExpression wurde korrekt erstellt.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
2 Das Interface PeanoNumberExpression wurde korrekt erstellt.[0, 1]0Kind does not match expected kind. {
expected package = h07.peano,
expected kind = INTERFACE,
expected name = PeanoNumberExpression,
expected modifier = ,
package = h07.peano,
kind = CLASS,
name = PeanoNumberExpressionFactory
}
expected <INTERFACE>
actual <CLASS>
H7.1.2 | ArithmeticExpression[0, 2]0
3 Das Interface ArithmeticExpression wurde korrekt erstellt.[0, 1]0Could not find Type ArithmeticExpression. Type is not defined or could not be found.
expected <true>
actual <false>
4 Das Interface PeanoArithmeticExpression wurde korrekt erstellt.[0, 1]0Could not find Type PeanoArithmeticExpression. Type is not defined or could not be found.
expected <true>
actual <false>
5 Alle Klassen und Methoden wurden korrekt benannt.[-1, 0]-1NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.NumberExpressionTest.testNaming(NumberExpressionTest.java:18)
6 Alle Klassen wurden im korrekten package definiert.[-1, 0]-1Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
H7.2 | Multiplikationstabelle[0, 3]0
H7.2.1 | Multiplikationstabelle[0, 3]0
7 Für ArithmeticExpression wurden nur Lambda-Ausdrücke in Standardform und für NumberExpression nur Lambda-Ausdrücke in Kurzform verwendet.[0, 1]0NoSuchElementException: No value present @ java.base/java.util.Optional.get(Optional.java:143)
8 Die Multiplikationstabelle gibt für lowerBound = upperBound die korrekten Werte aus.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 4 more failing tests
9 Die Multiplikationstabelle gibt für komplexere lowerBound und upperBound Werte die korrekten Werte aus.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 5 more failing tests
H7.3 | Peano Arithmetik[0, 10]0
H7.3.1 | PeanoAddExpression[0, 5]0
10 Die Klasse PeanoAddExpression wurde korrekt erstellt.[0, 1]0Could not find Type PeanoAddExpression. Type is not defined or could not be found.
expected <true>
actual <false>
11 Die Methode evaluate gibt für X + 0 das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
12 Die Methode evaluate gibt für 0 + X das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
13 Die Methode evaluate gibt für X + Y das korrekte Ergebnis zurück.[0, 2]0Could not initialize class h07.MethodReference

there are 7 more failing tests
14 Verbindliche Anforderung nicht erfüllt[-2, 0]-2NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.PeanoAddExpressionTest.testEvaluateRequirements(PeanoAddExpressionTest.java:87)
H7.3.2 | PeanoMultiplyExpression[0, 5]0
15 Die Klasse PeanoMultiplyExpression wurde korrekt erstellt.[0, 1]0Could not find Type PeanoMultiplyExpression. Type is not defined or could not be found.
expected <true>
actual <false>
16 Die Methode evaluate gibt für X * 0 das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
17 Die Methode evaluate gibt für 0 * X das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 4 more failing tests
18 Die Methode evaluate gibt für X * Y das korrekte Ergebnis zurück.[0, 2]0Could not initialize class h07.MethodReference

there are 7 more failing tests
19 Verbindliche Anforderung nicht erfüllt[-2, 0]-2NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.PeanoMultiplyExpressionTest.testEvaluateRequirements(PeanoMultiplyExpressionTest.java:87)
20 Alle Klassen und Methoden wurden korrekt benannt.[-1, 0]0
21 Alle Klassen wurden im korrekten package definiert.[-1, 0]-1Could not find Type PeanoAddExpression. Type is not defined or could not be found.
expected <true>
actual <false>
H7.4 | Funktionen höherer Ordnung[0, 15]0
H7.4.1 | Interfaces für Map erstellen[0, 2]0
22 Das Interface ConvertNumberToPeanoExpression wurde korrekt erstellt.[0, 1]0Could not find Type ConvertNumberToPeanoExpression. Type is not defined or could not be found.
expected <true>
actual <false>
23 Das Interface ConvertPeanoToNumberExpression wurde korrekt erstellt.[0, 1]0Could not find Type ConvertPeanoToNumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
H7.4.2 | Conversions Implementieren[0, 7]0
24 Die Klasse ConvertNumberToPeanoExpressionImpl wurde korrekt erstellt.[0, 1]0Could not find Type ConvertNumberToPeanoExpressionImpl. Type is not defined or could not be found.
expected <true>
actual <false>
25 Die Methode convert von ConvertNumberToPeanoExpressionImpl gibt für 0 das korrekte Ergebnis zurück.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>
26 Die Methode convert von ConvertNumberToPeanoExpressionImpl gibt für X das korrekte Ergebnis zurück.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 7 more failing tests
27 Die Klasse ConvertPeanoToNumberExpressionImpl wurde korrekt erstellt.[0, 1]0Could not find Type ConvertPeanoToNumberExpressionImpl. Type is not defined or could not be found.
expected <true>
actual <false>
28 Die Methode convert von ConvertPeanoToNumberExpressionImpl gibt für 0 das korrekte Ergebnis zurück.[0, 1]0Could not initialize class h07.MethodReference
29 Die Methode convert von ConvertPeanoToNumberExpressionImpl gibt für X das korrekte Ergebnis zurück.[0, 2]0Could not initialize class h07.MethodReference

there are 7 more failing tests
H7.4.3 | Von Zahlen zu Peano-Zahlen[0, 1]0
30 Die Methode fromNumberExpressions in PeanoNumberExpressionFactory wandelt einen Array von NumberExpressions korrekt um.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 4 more failing tests
H7.4.4 | Filter[0, 3]0
31 Filter gibt für ein leeres Array ein leeres Array zurück.[0, 1]0Could not find method NumberExpressionFactory.filter()
32 Filter gibt für ein Predicate, das immer true ist, das gesamte Array zurück und für ein Predicate, das immer false ist, ein leeres Array.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 3 more failing tests
33 Filter gibt für ein Predicate, welches nur durch vier teilbare Zahlen akzeptiert, nur die durch drei teilbaren Zahlen zurück.[0, 1]0Could not find Type NumberExpression. Type is not defined or could not be found.
expected <true>
actual <false>


there are 6 more failing tests
H7.4.5 | Fold[0, 2]0
34 Fold gibt für ein leeres Array das Initial zurück.[0, 1]0Could not initialize class h07.MethodReference

there are 2 more failing tests
35 Fold gibt für ein Array mit mehreren Elementen das korrekte Ergebnis zurück.[0, 1]0java.lang.NoClassDefFoundError: Could not initialize class h07.MethodReference

there are 3 more failing tests
36 Alle Klassen und Methoden wurden korrekt benannt.[-1, 0]-1NoClassDefFoundError: Could not initialize class h07.MethodReference @ h07.ConvertNumberToPeanoExpressionTest.testNaming(ConvertNumberToPeanoExpressionTest.java:18)
37 Alle Klassen wurden im korrekten package definiert.[-1, 0]-1Could not find Type ConvertNumberToPeanoExpression. Type is not defined or could not be found.
expected <true>
actual <false>
Gesamt[0, 32]0
"} \ No newline at end of file diff --git a/solution/H07/build/resources/jagr/main/submission-info.json b/solution/H07/build/resources/jagr/main/submission-info.json new file mode 100644 index 0000000..0152b79 --- /dev/null +++ b/solution/H07/build/resources/jagr/main/submission-info.json @@ -0,0 +1 @@ +{"assignmentId":"h07","jagrVersion":"0.10.3","sourceSets":[{"name":"main","files":{"java":["h07/NumberExpressionFactory.java","h07/peano/Successor.java","h07/peano/Zero.java","h07/peano/NaturalNumber.java","h07/peano/PeanoNumberExpressionFactory.java","h07/Main.java"]}},{"name":"test","files":{"java":["h07/ExampleJUnitTest.java"]}}],"dependencyConfigurations":{"implementation":["org.tudalgo:algoutils-student:0.7.2","org.jetbrains:annotations:26.0.0"],"testImplementation":["org.junit.jupiter:junit-jupiter:5.11.2"]},"repositoryConfigurations":[{"name":"maven","url":"https://s01.oss.sonatype.org/content/repositories/snapshots"},{"name":"maven2","url":"https://jitpack.io"},{"name":"MavenRepo","url":"https://repo.maven.apache.org/maven2/"}],"studentId":"ab12cdef","firstName":"sol_first","lastName":"sol_last"} \ No newline at end of file diff --git a/solution/H07/build/tmp/compileGraderPrivateJava/previous-compilation-data.bin b/solution/H07/build/tmp/compileGraderPrivateJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..3a5102f9e838458fe9b6a1d7e21dd0da3e8bff0a GIT binary patch literal 53552 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 literal 0 HcmV?d00001 diff --git a/solution/H07/build/tmp/compileTestJava/previous-compilation-data.bin b/solution/H07/build/tmp/compileTestJava/previous-compilation-data.bin new file mode 100644 index 0000000000000000000000000000000000000000..1051ea7b83879cd69945a061e3ffbf6aae022685 GIT binary patch literal 4086 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 hvk-RHQU*#`BV5E0`ZtAo;YR=f literal 0 HcmV?d00001 diff --git a/solution/H07/jagr.conf b/solution/H07/jagr.conf new file mode 100644 index 0000000..dbd1da5 --- /dev/null +++ b/solution/H07/jagr.conf @@ -0,0 +1,70 @@ +# The locations of the following directories may be configured here +dir { + # Grader jar ingest directory + graders=graders + # Runtime dependencies for submissions + libs=libs + # Rubrics export directory + rubrics=rubrics + # Submissions ingest directory + submissions=submissions + # Submission export directory + submissions-export=submissions-export +} +executor { + # + # The maximum amount of concurrency to use for grading. + # For a given concurrency n, Jagr will ensure that a maximum of n threads or processes are used concurrently that actively run + # submission code. + concurrency=4 + # + # The JVM arguments to use for grading. These arguments are passed to the JVM that runs the grading code. + # This only applies to the "process" mode, as the "thread" and "single" modes do not spawn a new JVM. + # + jvm-args=[] + # + # The executor mode to use. The following options are available: + # - "single" :: + # Runs every TestCycle consecutively in the main thread. This mode does not create any extra processes or threads for grading. + # + # - "thread" :: + # Creates a separate thread for every TestCycle. This mode greatly speeds up the grading process, especially with a large + # amount of submissions. The overhead of creating, managing and synchronizing threads is minimal compared to the performance + # benefits. However, this mode has the danger of creating "unkillable" threads (e.g. from certain kinds of infinite loops) + # which dramatically slow down the grading process through resource starvation of the host machine. + # + # The maximum number of concurrent threads used for grading is defined by the option "concurrency". + # + # - "process" :: + # Creates a separate process for every TestCycle. This mode has the most overhead, but is also the most defensive against + # "badly behaving" code. A certain amount of sandboxing can be achieved in this mode, which is not possible in the other modes + # such as "thread" or "single". + # + # The maximum number of concurrent child process used for grading is defined by the option "concurrency". + mode=process + # + # The grading thread's maximum permitted elapsed userTime in milliseconds since the last timeout before an + # AssertionFailedError is thrown. If a thread's userTime satisfies + # (userTime - lastTimeout) > individualTimeout, + # the current userTime is stored for comparison later, and an AssertionFailedError is thrown to be caught by JUnit. + timeout-individual=10000 + # + # The grading thread's maximum permitted elapsed userTime in milliseconds (from thread start) before an + # AssertionFailedError is thrown. If a thread's userTime satisfies + # ((userTime - lastTimeout) > individualTimeout) && (userTime > totalTimeout), + # an AssertionFailedError is thrown to be caught by JUnit. Note that lastTimeout is not reset in this case, and all further + # invocations of checkTimeout() will result in an AssertionFailedError + timeout-total=150000 +} +extras { + moodle-unpack { + assignment-id-regex=".*Abgabe[^0-9]*(?[0-9]{1,2}).*[.]zip" + enabled=true + student-regex=".* - (?([a-z]{2}[0-9]{2}[a-z]{4})|([a-z]+_[a-z]+))/submissions/.*[.]jar" + } +} +transformers { + timeout { + enabled=true + } +} diff --git a/solution/H07/src/main b/solution/H07/src/main deleted file mode 120000 index e2862ca..0000000 --- a/solution/H07/src/main +++ /dev/null @@ -1 +0,0 @@ -/home/osh/Desktop/FOP-2425-Marathon/H07/src/main \ No newline at end of file diff --git a/solution/H07/src/test b/solution/H07/src/test deleted file mode 120000 index b48ee30..0000000 --- a/solution/H07/src/test +++ /dev/null @@ -1 +0,0 @@ -/home/osh/Desktop/FOP-2425-Marathon/H07/src/test \ No newline at end of file diff --git a/solution/H08/.editorconfig b/solution/H08/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/solution/H08/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/solution/H07/.gitignore b/solution/H08/.gitignore similarity index 99% rename from solution/H07/.gitignore rename to solution/H08/.gitignore index 528b8e0..7b957c2 100644 --- a/solution/H07/.gitignore +++ b/solution/H08/.gitignore @@ -84,5 +84,4 @@ gradle-app.setting *.hprof screenshots/ - jagr.conf diff --git a/solution/H08/README.md b/solution/H08/README.md new file mode 100644 index 0000000..3c63c8d --- /dev/null +++ b/solution/H08/README.md @@ -0,0 +1,4 @@ +# Musterlösung zu Hausübung 08 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/solution/H08/build.gradle.kts b/solution/H08/build.gradle.kts new file mode 100644 index 0000000..1a3d4c1 --- /dev/null +++ b/solution/H08/build.gradle.kts @@ -0,0 +1,48 @@ +plugins { + alias(libs.plugins.algomate) + alias(libs.plugins.style) +} + +version = file("version").readLines().first() + +exercise { + assignmentId.set("h08") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "ab12cdef" + firstName = "sol_first" + lastName = "sol_last" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting + val graderPrivate by creating { + parent(graderPublic) + graderName.set("FOP-2425-H08-Private") + rubricProviderName.set("h08.H08_RubricProvider") + config.set( + org.sourcegrade.jagr.launcher.env.Config( + executor = org.sourcegrade.jagr.launcher.env.Executor( + jvmArgs = listOf("-ea"), + ) + ) + ) + } + } +} + +application { + applicationDefaultJvmArgs += "-ea" +} diff --git a/solution/H08/gradle/libs.versions.toml b/solution/H08/gradle/libs.versions.toml new file mode 100644 index 0000000..2a961b5 --- /dev/null +++ b/solution/H08/gradle/libs.versions.toml @@ -0,0 +1,3 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } +style = { id = "org.sourcegrade.style", version = "3.0.0" } diff --git a/solution/H07/gradle/wrapper/gradle-wrapper.jar b/solution/H08/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from solution/H07/gradle/wrapper/gradle-wrapper.jar rename to solution/H08/gradle/wrapper/gradle-wrapper.jar diff --git a/solution/H08/gradle/wrapper/gradle-wrapper.properties b/solution/H08/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..36074ad --- /dev/null +++ b/solution/H08/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/solution/H07/gradlew b/solution/H08/gradlew similarity index 100% rename from solution/H07/gradlew rename to solution/H08/gradlew diff --git a/solution/H07/gradlew.bat b/solution/H08/gradlew.bat similarity index 100% rename from solution/H07/gradlew.bat rename to solution/H08/gradlew.bat diff --git a/solution/H08/settings.gradle.kts b/solution/H08/settings.gradle.kts new file mode 100644 index 0000000..959cdf2 --- /dev/null +++ b/solution/H08/settings.gradle.kts @@ -0,0 +1,15 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + maven("https://jitpack.io") + mavenCentral() + } +} + +<<<<<<<< Updated upstream:solution/H08/settings.gradle.kts +rootProject.name = "H08-Root" +======== +rootProject.name = "H09-Student" +>>>>>>>> Stashed changes:H09/settings.gradle.kts diff --git a/solution/H08/src/graderPrivate/java/h08/H08_1_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_1_TestsPrivate.java new file mode 100644 index 0000000..1dcadc8 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_1_TestsPrivate.java @@ -0,0 +1,170 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.Links; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.mockito.Mockito; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.time.LocalDate; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the task H08.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.1 | Have your ID ready") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_1_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "firstName", JsonNode::asText, + "lastName", JsonNode::asText, + "dateOfBirth", JsonConverters::toLocalDate, + "expectedInitials", JsonNode::asText, + "expectedHash", JsonNode::asText + ); + + /** + * The link to the passenger ID field of the Passenger class. + */ + private FieldLink passengerIDLink; + + /** + * The link to the first name field of the Passenger class. + */ + private FieldLink firstNameLink; + + /** + * The link to the last name field of the Passenger class. + */ + private FieldLink lastNameLink; + + /** + * The link to the date of birth field of the Passenger class. + */ + private FieldLink dateOfBirthLink; + + /** + * The link to the generatePassengerID method of the Passenger class. + */ + private MethodLink generatePassengerIDLink; + + /** + * The instance of the Passenger class to test. + */ + private Passenger instance; + + /** + * Sets up the global test environment. + */ + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + TypeLink passenger = Links.getType(Passenger.class); + passengerIDLink = Links.getField(passenger, "passengerID"); + firstNameLink = Links.getField(passenger, "firstName"); + lastNameLink = Links.getField(passenger, "lastName"); + dateOfBirthLink = Links.getField(passenger, "dateOfBirth"); + generatePassengerIDLink = Links.getMethod(passenger, "generatePassengerID", String.class, String.class, LocalDate.class); + } + + /** + * Sets up the test environment before each test. + */ + @BeforeEach + void setup() { + instance = null; + } + + /** + * Returns pre-setup test information for the given parameters and instance to test the generatePassengerID method. + * + * @param parameters the test input and expected output parameters + * + * @return pre-setup test information for the given parameters and instance + */ + private TestInformation testInformation(JsonParameterSet parameters) { + String firstName = parameters.getString("firstName"); + String lastName = parameters.getString("lastName"); + LocalDate dateOfBirth = parameters.get("dateOfBirth"); + String passengerID = parameters.getString("passengerID"); + return TestInformation.builder() + .subject(passengerID) + .input(builder -> builder.add("firstName", firstName) + .add("lastName", lastName) + .add("dateOfBirth", dateOfBirth) + ).expect(builder -> builder.add("passengerID", passengerID)) + .actual(builder -> builder.add("passengerID", this.passengerIDLink.get(instance))) + .build(); + } + + /** + * Invokes the generatePassengerID method of the Passenger class with the given parameters. + * + * @param parameters the test input and expected output parameters + * + * @return the generated passenger ID + * @throws Throwable if an error occurs during the test execution + */ + private String invokeMethod(JsonParameterSet parameters) throws Throwable { + // Test setup + String firstName = parameters.getString("firstName"); + String lastName = parameters.getString("lastName"); + LocalDate dateOfBirth = parameters.get("dateOfBirth"); + + // Test execution + instance = Mockito.mock(Passenger.class); + this.firstNameLink.set(instance, firstName); + this.lastNameLink.set(instance, lastName); + this.dateOfBirthLink.set(instance, dateOfBirth); + String result = generatePassengerIDLink.invoke(instance, firstName, lastName, dateOfBirth); + this.passengerIDLink.set(instance, result); + return result; + } + + @DisplayName("Die Methode generatePassengerID stellt sicher, dass die ersten zwei Zeichen der ID die Initialen des Vornamens und Nachnamens sind.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_1_generatePassengerID.json", customConverters = CUSTOM_CONVERTERS) + void testGeneratePassengerIDNameInitials(JsonParameterSet parameters) throws Throwable { + // Test execution + String actual = invokeMethod(parameters); + + // Test verification + String expected = parameters.getString("expectedInitials"); + Assertions2.assertEquals(expected, actual.substring(0, 2), testInformation(parameters), + comment -> "The two initials does not match the initials from the first and last name."); + } + + @DisplayName("Die Methode generatePassengerID stellt sicher, dass der Hash-Code des Datums korrekt im zweiten Teil der ID enthalten ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_1_generatePassengerID.json", customConverters = CUSTOM_CONVERTERS) + void testGeneratePassengerIDDateHash(JsonParameterSet parameters) throws Throwable { + // Test execution + String actual = invokeMethod(parameters); + + // Test verification + String expected = parameters.getString("expectedHash"); + Assertions2.assertEquals(expected, actual.substring(2), testInformation(parameters), + comment -> "Hash does not match expected hash."); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_2_1_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_2_1_TestsPrivate.java new file mode 100644 index 0000000..4856819 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_2_1_TestsPrivate.java @@ -0,0 +1,164 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.Links; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.mockito.Mockito; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.ConstructorLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; + +/** + * Defines the private tests for the subtask H08.2.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H8.2.1 | Let’s get in shape.") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_2_1_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "flightNumber", node -> node.isNull() ? null : node.asText(), + "departure", node -> node.isNull() ? null : node.asText(), + "destination", node -> node.isNull() ? null : node.asText(), + "departureTime", node -> node.isNull() ? null : JsonConverters.toLocalDateTime(node), + "initialSeats", JsonNode::asInt, + "availableSeats", JsonNode::asInt, + "message", JsonNode::asText + ); + + /** + * The link to the flight class. + */ + private TypeLink typeLink; + + /** + * Sets up the global test environment. + */ + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + typeLink = Links.getType(Flight.class); + } + + @DisplayName("Die Methode validateFlightNumber wirft keinen Fehler für valide Eingaben.") + @Test + void testValidateFlightNumber() throws Throwable { + String[] flightNumbers = {"LH123", "LH1234"}; + Flight flight = Mockito.mock(Flight.class, Mockito.CALLS_REAL_METHODS); + MethodLink methodLink = Links.getMethod(this.typeLink, "validateFlightNumber", String.class); + + for (String flightNumber : flightNumbers) { + TestInformation info = TestInformation.builder() + .subject(methodLink) + .input(builder -> builder.add("flightNumber", flightNumber)) + .expect(builder -> builder.cause(null)) + .build(); + + Assertions2.call( + () -> methodLink.invoke(flight, flightNumber), + info, + comment -> "Valid flight number should not throw an exception"); + } + } + + @DisplayName("Die Methode validateFlightNumber wirft einen Fehler für invalide Eingaben.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_2_1_testValidateFlightNumberException.json", customConverters = CUSTOM_CONVERTERS) + void testValidateFlightNumberException(JsonParameterSet parameters) throws Throwable { + String flightNumber = parameters.get("flightNumber"); + Flight flight = Mockito.mock(Flight.class, Mockito.CALLS_REAL_METHODS); + MethodLink methodLink = Links.getMethod(this.typeLink, "validateFlightNumber", String.class); + + TestInformation info = TestInformation.builder() + .subject(methodLink) + .input(builder -> builder.add("flightNumber", flightNumber)) + .expect(builder -> builder.cause(AssertionError.class)) + .build(); + + assertAssertions(() -> methodLink.invoke(flight, flightNumber), info); + } + + @DisplayName("Der Konstruktor der Klasse Flight enthält führt keine assert-Anweisungen aus.") + @Test + void testFlightConstructor() throws Throwable { + String flightNumber = "LH1234"; + String departure = "FRA"; + String destination = "ICN"; + LocalDateTime departureTime = LocalDateTime.of(2025, 2, 7, 13, 0); + int initialSeats = 0; + + List parameterTypes = Stream.of(String.class, String.class, String.class, LocalDateTime.class, int.class) + .map(BasicTypeLink::of) + .toList(); + ConstructorLink constructor = typeLink.getConstructor(Matcher.of(m -> m.typeList().equals(parameterTypes))); + + TestInformation info = TestInformation.builder() + .subject(constructor) + .input(builder -> builder + .add("flightNumber", flightNumber) + .add("departure", departure) + .add("destination", destination) + .add("departureTime", departureTime) + .add("initialSeats", initialSeats) + ).expect(builder -> builder.cause(null)) + .build(); + Assertions2.call( + () -> new Flight(flightNumber, departure, destination, departureTime, initialSeats), + info, + comment -> "Constructor should not throw an exception for valid input." + ); + } + + @DisplayName("Der Konstruktor der Klasse Flight enthält assert-Anweisungen, die die Eingaben überprüfen.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_2_1_testFlightConstructor.json", customConverters = CUSTOM_CONVERTERS) + void testFlightConstructorException(JsonParameterSet parameters) throws Throwable { + String flightNumber = parameters.get("flightNumber"); + String departure = parameters.get("departure"); + String destination = parameters.get("destination"); + LocalDateTime departureTime = parameters.get("departureTime"); + int initialSeats = parameters.getInt("initialSeats"); + + List parameterTypes = Stream.of(String.class, String.class, String.class, LocalDateTime.class, int.class) + .map(BasicTypeLink::of) + .toList(); + ConstructorLink constructor = typeLink.getConstructor(Matcher.of(m -> m.typeList().equals(parameterTypes))); + + TestInformation info = TestInformation.builder() + .subject(constructor) + .input(builder -> builder + .add("flightNumber", flightNumber) + .add("departure", departure) + .add("destination", destination) + .add("departureTime", departureTime) + .add("initialSeats", initialSeats) + ).expect(builder -> builder.cause(AssertionError.class)) + .build(); + + assertAssertions(() -> new Flight(flightNumber, departure, destination, departureTime, initialSeats), info); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_2_2_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_2_2_TestsPrivate.java new file mode 100644 index 0000000..3164eea --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_2_2_TestsPrivate.java @@ -0,0 +1,119 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Mocks; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.ConstructorLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.2.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.2.2 | Fasten your seatbelts") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_2_2_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "preFlight", JsonConverters::toFlight, + "postFlight", JsonConverters::toFlight + ); + + @DisplayName("Die NoSeatsAvailableException ist korrekt implementiert.") + @Test + void testNoSeatsAvailableException() throws Throwable { + ClassReference reference = ClassReference.NO_SEATS_AVAILABLE_EXCEPTION; + assertExceptionDefinedCorrectly(reference); + TypeLink typeLink = reference.getLink(); + List constructorParameterTypes = List.of(BasicTypeLink.of(String.class)); + ConstructorLink constructorLink = typeLink.getConstructor( + Matcher.of(c -> c.typeList().equals(constructorParameterTypes)) + ); + String flightNumber = "YF0802"; + Throwable instance = constructorLink.invoke(flightNumber); + String actualMessage = instance.getMessage(); + String expectedMessage = "No seats available for flight: YF0802"; + TestInformation info = TestInformation.builder() + .subject(typeLink) + .input(builder -> builder.add("flightNumber", flightNumber)) + .expect(builder -> builder.add("getMessage()", expectedMessage)) + .actual(builder -> builder.add("getMessage()", actualMessage)) + .build(); + Assertions2.assertEquals( + expectedMessage, + actualMessage, + info, + comment -> "Message does not match expected message." + ); + } + + @DisplayName("Die Methode bookSeat() reserviert korrekt Sitzplätze.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_2_2_testBookSeat.json", customConverters = CUSTOM_CONVERTERS) + void testBookSeat(JsonParameterSet parameters) throws Throwable { + Flight preFlight = parameters.get("preFlight"); + Flight postFlight = parameters.get("postFlight"); + TestInformation.TestInformationBuilder infoBuilder = TestInformation.builder() + .input(builder -> builder.add("flight", preFlight)) + .expect(builder -> builder.add("flight", postFlight)); + preFlight.bookSeat(); + TestInformation info = infoBuilder + .actual(builder -> builder.add("flight", postFlight)) + .build(); + Assertions2.assertTrue( + TutorUtils.equalFlight(postFlight, preFlight), + info, + comment -> "Flight does not match expected flight." + ); + } + + @DisplayName("Die Methode bookSeat() reserviert korrekt Sitzplätze.") + @Test + @SuppressWarnings("unchecked") + void testBookSeatException() throws Throwable { + Flight flight = Mocks.createFlight( + "LH712", + "FRA", + "ICN", + LocalDateTime.of(2025, 2, 7, 13, 0), + 100, + 0 + ); + ClassReference reference = ClassReference.NO_SEATS_AVAILABLE_EXCEPTION; + reference.assertDefined(); + Class exceptionClass = (Class) reference.getLink().reflection(); + TestInformation info = TestInformation.builder() + .input(builder -> builder.add("flight", flight)) + .expect(builder -> builder.cause(exceptionClass)) + .build(); + Assertions2.assertThrows( + exceptionClass, + flight::bookSeat, + info, + comment -> "%s should be thrown.".formatted(exceptionClass.getSimpleName()) + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_3_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_3_TestsPrivate.java new file mode 100644 index 0000000..224a318 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_3_TestsPrivate.java @@ -0,0 +1,62 @@ +package h08; + +import h08.assertions.ClassReference; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; + +/** + * Defines the private tests for the task H08.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.3 | Exception Handling") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_3_TestsPrivate extends H08_Tests { + + @DisplayName("Die FlightManagementException ist korrekt implementiert.") + @Test + void testFlightManagementException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.FLIGHT_MANAGEMENT_EXCEPTION); + } + + @DisplayName("Die BookingManagementException ist korrekt implementiert.") + @Test + void testBookingManagementException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.BOOKING_MANAGEMENT_EXCEPTION); + } + + @DisplayName("Die FlightNotFoundException ist korrekt implementiert.") + @Test + void testFlightNotFoundException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.FLIGHT_NOT_FOUND_EXCEPTION); + } + + @DisplayName("Die BookingNotFoundException ist korrekt implementiert.") + @Test + void testBookingNotFoundException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.BOOKING_NOT_FOUND_EXCEPTION); + } + + @DisplayName("Die InvalidBookingException ist korrekt implementiert.") + @Test + void testInvalidBookingException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.INVALID_BOOKING_EXCEPTION); + } + + @DisplayName("Die BookingAlreadyCancelledException ist korrekt implementiert.") + @Test + void testBookingAlreadyCancelledException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.BOOKING_ALREADY_CANCELLED_EXCEPTION); + } + + @DisplayName("Die DuplicateBookingException ist korrekt implementiert.") + @Test + void testDuplicateBookingException() throws Throwable { + assertExceptionDefinedCorrectly(ClassReference.DUPLICATE_BOOKING_EXCEPTION); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_4_1_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_4_1_TestsPrivate.java new file mode 100644 index 0000000..7c1d188 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_4_1_TestsPrivate.java @@ -0,0 +1,117 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.Links; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.4.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.4.1 | Adding a Flight") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_4_1_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "preAirport", JsonConverters::toAirport, + "postAirport", JsonConverters::toAirport, + "flight", JsonConverters::toFlight, + "isDeparting", JsonNode::asBoolean + ); + + /** + * The link to the addFlight method of the Airport class. + */ + private MethodLink methodLink; + + /** + * The link to the addFlight method of the Airport class. + */ + @BeforeAll + protected void globalSetup() { + methodLink = Links.getMethod(Links.getType(Airport.class), "addFlight", Flight.class, boolean.class); + } + + private TestInformation.TestInformationBuilder infoBuilder(JsonParameterSet parameters) { + Airport preAirport = parameters.get("preAirport"); + Flight flight = parameters.get("flight"); + boolean isDeparting = parameters.get("isDeparting"); + return TestInformation.builder() + .subject(methodLink) + .input(builder -> builder + .add("airport", preAirport) + .add("flight", flight) + .add("isDeparting", isDeparting)); + } + + @DisplayName("Die Methode addFlight fügt Flüge korrekt zu abgehenden oder ankommenden Flügen hinzu.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_1_testAddFlight.json", customConverters = CUSTOM_CONVERTERS) + void testAddFlight(JsonParameterSet parameters) throws Throwable { + Airport preAirport = parameters.get("preAirport"); + Airport postAirport = parameters.get("postAirport"); + Flight flight = parameters.get("flight"); + boolean isDeparting = parameters.get("isDeparting"); + + TestInformation info = infoBuilder(parameters).expect(builder -> builder + .cause(null) + .add("airport", postAirport)) + .build(); + Assertions2.call( + () -> preAirport.addFlight(flight, isDeparting), + info, + comment -> "Valid depature/destination should not cause an exception." + ); + Assertions2.assertEquals( + postAirport, + preAirport, + info, + comment -> "The airport should be updated correctly after adding the flight." + ); + } + + @DisplayName("Die Methode prüft und behandelt korrekt falsche Flughafencodes.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_1_testAddFlightException.json", customConverters = CUSTOM_CONVERTERS) + void testAddFlightException(JsonParameterSet parameters) throws Throwable { + Airport preAirport = parameters.get("preAirport"); + Airport postAirport = parameters.get("postAirport"); + Flight flight = parameters.get("flight"); + boolean isDeparting = parameters.get("isDeparting"); + + TestInformation info = infoBuilder(parameters) + .expect(builder -> builder.cause(IllegalAccessError.class)) + .build(); + Assertions2.assertThrows( + IllegalArgumentException.class, + () -> preAirport.addFlight(flight, isDeparting), + info, + comment -> "Invalid depature/destination should cause an exception." + ); + Assertions2.assertEquals( + postAirport, + preAirport, + info, + comment -> "The airport should not be updated when an exception occurs." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_4_2_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_4_2_TestsPrivate.java new file mode 100644 index 0000000..ca58b03 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_4_2_TestsPrivate.java @@ -0,0 +1,137 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Links; +import h08.mocks.FakeAirport; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.4.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.4.2 | Removing a Flight") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_4_2_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "preAirport", JsonConverters::toAirport, + "postAirport", JsonConverters::toAirport, + "flight", JsonConverters::toFlight, + "isDeparting", JsonNode::asBoolean, + "message", JsonNode::asText + ); + + /** + * The link to the removeFlight method of the Airport class. + */ + private MethodLink methodLink; + + /** + * The link to the addFlight method of the Airport class. + */ + @BeforeAll + protected void globalSetup() { + methodLink = Links.getMethod(Links.getType(Airport.class), "removeFlight", String.class, boolean.class); + } + + private TestInformation.TestInformationBuilder infoBuilder(JsonParameterSet parameters) { + Airport preAirport = parameters.get("preAirport"); + String flightNumber = parameters.get("flightNumber"); + boolean isDeparting = parameters.get("isDeparting"); + return TestInformation.builder() + .subject(methodLink) + .input(builder -> builder + .add("airport", preAirport) + .add("flightNumber", flightNumber) + .add("isDeparting", isDeparting)); + } + + @DisplayName("Die Methode removeFlight entfernt Flüge korrekt aus den Listen.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_2_testRemoveFlight.json", customConverters = CUSTOM_CONVERTERS) + void testRemoveFlight(JsonParameterSet parameters) throws Throwable { + FakeAirport preAirport = (FakeAirport) parameters.get("preAirport"); + FakeAirport postAirport = (FakeAirport) parameters.get("postAirport"); + String flightNumber = parameters.get("flightNumber"); + boolean isDeparting = parameters.get("isDeparting"); + + TestInformation info = infoBuilder(parameters).expect(builder -> builder + .cause(null) + .add("airport", postAirport)) + .build(); + Assertions2.call( + () -> preAirport.removeFlight(flightNumber, isDeparting), + info, + comment -> "Valid depature/destination should not cause an exception." + ); + Comparator cmp = Comparator.nullsLast(Comparator.comparing(Flight::getFlightNumber)); + Arrays.sort(preAirport.getDepartingFlights(), cmp); + Arrays.sort(preAirport.getArrivingFlights(), cmp); + Arrays.sort(postAirport.getDepartingFlights(), cmp); + Arrays.sort(postAirport.getArrivingFlights(), cmp); + Assertions2.assertEquals( + postAirport, + preAirport, + info, + comment -> "The airport should be updated correctly after adding the flight." + ); + } + + @DisplayName("Die Methode wirft korrekt eine FlightNotFoundException, wenn der Flug nicht gefunden wird.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_2_testRemoveFlightException.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void testRemoveFlightException(JsonParameterSet parameters) throws Throwable { + Airport preAirport = parameters.get("preAirport"); + Airport postAirport = parameters.get("postAirport"); + String flightNumber = parameters.get("flightNumber"); + boolean isDeparting = parameters.get("isDeparting"); + + TestInformation info = infoBuilder(parameters) + .expect(builder -> builder.cause(IllegalAccessError.class)) + .build(); + ClassReference reference = ClassReference.FLIGHT_NOT_FOUND_EXCEPTION; + Class exceptionClass = (Class) reference.getLink().reflection(); + Throwable throwable = Assertions2.assertThrows( + exceptionClass, + () -> preAirport.removeFlight(flightNumber, isDeparting), + info, + comment -> "Invalid depature/destination should cause an exception." + ); + String message = parameters.get("message"); + Assertions2.assertEquals( + message, + throwable.getMessage(), + info, + comment -> "The message does not match the expected message." + ); + Assertions2.assertEquals( + postAirport, + preAirport, + info, + comment -> "The airport should not be updated when an exception occurs." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_4_3_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_4_3_TestsPrivate.java new file mode 100644 index 0000000..497aae4 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_4_3_TestsPrivate.java @@ -0,0 +1,120 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Links; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.4.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.4.3 | Getting a Flight") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_4_3_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "airport", JsonConverters::toAirport, + "flight", JsonConverters::toFlight, + "isDeparting", JsonNode::asBoolean, + "message", JsonNode::asText + ); + + /** + * The link to the getFlight method of the Airport class. + */ + private MethodLink methodLink; + + /** + * The link to the addFlight method of the Airport class. + */ + @BeforeAll + protected void globalSetup() { + methodLink = Links.getMethod(Links.getType(Airport.class), "getFlight", String.class, boolean.class); + } + + private TestInformation.TestInformationBuilder infoBuilder(JsonParameterSet parameters) { + Airport preAirport = parameters.get("airport"); + Flight flight = parameters.get("flight"); + boolean isDeparting = parameters.get("isDeparting"); + return TestInformation.builder() + .subject(methodLink) + .input(builder -> builder + .add("airport", preAirport) + .add("flightNumber", flight.getFlightNumber()) + .add("isDeparting", isDeparting)); + } + + @DisplayName("Die Methode getFlight gibt Flüge korrekt zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_3_testGetFlight.json", customConverters = CUSTOM_CONVERTERS) + void testGetFlight(JsonParameterSet parameters) throws Throwable { + Airport airport = parameters.get("airport"); + Flight flight = parameters.get("flight"); + boolean isDeparting = parameters.get("isDeparting"); + + TestInformation.TestInformationBuilder infoBuilder = infoBuilder(parameters) + .expect(builder -> builder.add("flight", flight)); + AtomicReference searchedFlight = new AtomicReference<>(); + Assertions2.call( + () -> searchedFlight.set(airport.getFlight(flight.getFlightNumber(), isDeparting)), + infoBuilder.build(), + comment -> "Searching for an existing flight should not cause an exception." + ); + Assertions2.assertTrue( + TutorUtils.equalFlight(flight, searchedFlight.get()), + infoBuilder.actual(builder -> builder.add("flight", searchedFlight.get())).build(), + comment -> "Searched flight does not match expected search result." + ); + } + + @DisplayName("Die Methode wirft korrekt eine FlightNotFoundException, wenn der Flug nicht existiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_3_testGetFlightException.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void testGetFlightException(JsonParameterSet parameters) throws Throwable { + Airport airport = parameters.get("airport"); + Flight flight = parameters.get("flight"); + boolean isDeparting = parameters.get("isDeparting"); + + ClassReference reference = ClassReference.FLIGHT_NOT_FOUND_EXCEPTION; + Class exceptionClass = (Class) reference.getLink().reflection(); + TestInformation info = infoBuilder(parameters) + .expect(builder -> builder.cause(exceptionClass)) + .build(); + + Throwable throwable = Assertions2.assertThrows( + exceptionClass, + () -> airport.getFlight(flight.getFlightNumber(), isDeparting), + info, + comment -> "Invalid depature/destination should cause an exception." + ); + String message = parameters.get("message"); + Assertions2.assertEquals( + message, + throwable.getMessage(), + info, + comment -> "The message does not match the expected message." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_4_4_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_4_4_TestsPrivate.java new file mode 100644 index 0000000..316dae3 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_4_4_TestsPrivate.java @@ -0,0 +1,113 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Links; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.4.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.4.4 | Removing a booking") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_4_4_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "booking", JsonConverters::toBooking, + "isCancelled", JsonNode::asInt, + "message", JsonNode::asText + ); + + /** + * The link to the cancelBooking method of the Booking class. + */ + private MethodLink methodLink; + + /** + * Sets up the global test environment. + */ + @BeforeAll + protected void globalSetup() { + methodLink = Links.getMethod(BasicTypeLink.of(Booking.class), "cancelBooking"); + } + + /** + * Initializes the test with the given parameters. + * + * @param parameters the parameters to initialize the test with + */ + private TestInformation.TestInformationBuilder info(JsonParameterSet parameters) { + Booking booking = parameters.get("booking"); + boolean isCancelled = parameters.getBoolean("isCancelled"); + return TestInformation.builder() + .subject(methodLink) + .input(builder -> builder + .add("booking", booking) + .add("isCancelled", isCancelled) + ); + } + + @DisplayName("Die Methode getFlight gibt Flüge korrekt zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_4_testCancelBooking.json", customConverters = CUSTOM_CONVERTERS) + void testCancelBooking(JsonParameterSet parameters) throws Throwable { + Booking booking = parameters.get("booking"); + TestInformation info = info(parameters) + .expect(builder -> builder + .cause(null). + add("isCancelled", true) + ).build(); + Assertions2.call(booking::cancelBooking, info, + comment -> "Something went wrong while cancelling the booking."); + Assertions2.assertTrue(booking.isCancelled(), info, comment -> "The status of the cancellation is not correct."); + } + + @DisplayName("Die Methode wirft korrekt eine BookingAlreadyCancelledException, wenn die Buchung bereits storniert wurde.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_4_4_testCancelBookingException.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void testCancelBookingException(JsonParameterSet parameters) throws Throwable { + ClassReference reference = ClassReference.BOOKING_ALREADY_CANCELLED_EXCEPTION; + Class exceptionType = (Class) reference.getLink().reflection(); + TestInformation info = info(parameters) + .expect(builder -> builder + .cause(exceptionType) + .add("isCancelled", parameters.getBoolean("isCancelled"))) + .build(); + Booking booking = parameters.get("booking"); + Throwable exception = Assertions2.assertThrows( + exceptionType, + booking::cancelBooking, + info, + comment -> "Cannot cancel a booking that has already been cancelled." + ); + String message = parameters.get("message"); + Assertions2.assertEquals( + message, + exception.getMessage(), + info, + comment -> "Exception message does not match expected message." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_5_1_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_5_1_TestsPrivate.java new file mode 100644 index 0000000..0c69262 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_5_1_TestsPrivate.java @@ -0,0 +1,238 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.Links; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.5.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H8.5.1 | Airport and Flight Lookup") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_5_1_TestsPrivate extends H08_Tests { + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "flightManagement", JsonConverters::toFlightManagement, + "airport", JsonConverters::toAirport, + "flightNumber", JsonNode::asText, + "flight", node -> node.isNull() ? null : JsonConverters.toFlight(node), + "message", node -> node.isNull() ? null : node.asText() + ); + + /** + * Store the old standard output stream to restore it after the tests. + */ + private PrintStream out; + + /** + * The test class to test the methods. + */ + private TypeLink type; + + /** + * Sets up the global test environment. + */ + @BeforeAll + protected void globalSetup() { + type = Links.getType(FlightManagement.class); + out = System.out; + } + + /** + * Tears down the global test environment. + */ + @AfterAll + void globalTearDown() { + System.setOut(out); + } + + + @DisplayName("Die Methode searchAirport findet Flughäfen korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_1_testSearchAirport.json", customConverters = CUSTOM_CONVERTERS) + void testSearchAirport(JsonParameterSet parameters) throws Throwable { + MethodLink method = Links.getMethod(type, "searchAirport", String.class); + FlightManagement management = parameters.get("flightManagement"); + Airport airport = parameters.get("airport"); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("Flight Management", management) + .add("airportCode", airport.getAirportCode()) + ) + .expect(builder -> builder + .cause(null) + .add("Result", airport)) + .build(); + + AtomicReference result = new AtomicReference<>(); + Assertions2.call(() -> result.set(method.invoke(management, airport.getAirportCode())), + info, + comment -> "Unexpected exception occurred while searching for the airport!" + ); + Assertions2.assertEquals( + airport, + result.get(), + info, + comment -> "Wrong search result!" + ); + + } + + @DisplayName("Die Methode searchAirport findet keine Flughäfen korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_1_testSearchAirportException.json", customConverters = CUSTOM_CONVERTERS) + void testSearchAirportException(JsonParameterSet parameters) throws Throwable { + MethodLink method = Links.getMethod(type, "searchAirport", String.class); + FlightManagement management = parameters.get("flightManagement"); + String airportCode = parameters.get("airportCode"); + String message = parameters.get("message"); + + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("Flight Management", management) + .add("airportCode", airportCode) + ) + .expect(builder -> builder.cause(Exception.class)) + .build(); + + Throwable exception = Assertions2.assertThrows( + Exception.class, + () -> method.invoke(management, airportCode), + info, + comment -> "Airport should not be found." + ); + Assertions2.assertEquals( + message, + exception.getMessage(), + info, + comment -> "Exception message does not match the expected message." + ); + } + + @DisplayName("Die Methode searchFlight durchsucht Flüge korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_1_testSearchFlight.json", customConverters = CUSTOM_CONVERTERS) + void testSearchFlight(JsonParameterSet parameters) throws Throwable { + MethodLink method = Links.getMethod(type, "searchFlight", Airport.class, String.class); + FlightManagement management = parameters.get("flightManagement"); + Airport airport = parameters.get("airport"); + String flightNumber = parameters.get("flightNumber"); + Flight flight = parameters.get("flight"); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("Flight Management", management) + .add("airport", airport) + .add("flightNumber", flightNumber)) + .expect(builder -> builder + .cause(null) + .add("Result", String.valueOf(flight))) + .build(); + AtomicReference result = new AtomicReference<>(); + Assertions2.call( + () -> result.set(method.invoke(management, airport, flightNumber)), + info, + comment -> "Unexpected exception occurred while searching for the airport." + ); + Assertions2.assertTrue( + TutorUtils.equalFlight(flight, result.get()), + info, + comment -> "The result of the searched flight does not match the expected flight." + ); + } + + @DisplayName("Die Methode getFlight gibt Flüge korrekt zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_1_testGetFlight.json", customConverters = CUSTOM_CONVERTERS) + void testGetFlight(JsonParameterSet parameters) throws Throwable { + MethodLink method = Links.getMethod(type, "getFlight", String.class); + FlightManagement management = parameters.get("flightManagement"); + Flight flight = parameters.get("flight"); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("Flight Management", management) + .add("flightNumber", flight.getFlightNumber())) + .expect(builder -> builder + .cause(null) + .add("Result", flight) + ).build(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setOut(new PrintStream(baos)); + AtomicReference result = new AtomicReference<>(); + Assertions2.call(() -> result.set(method.invoke(management, flight.getFlightNumber())), + info, + comment -> "Unexpected exception occurred while searching for the airport." + ); + Assertions2.assertTrue( + TutorUtils.equalFlight(flight, result.get()), + info, + comment -> "The result of the searched flight does not match the expected flight." + ); + } + + @DisplayName("Die Methode getFlight null zurück, falls kein Flug gefunden werden kann.") + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_1_testGetFlightNull.json", customConverters = CUSTOM_CONVERTERS) + void testGetFlightNull(JsonParameterSet parameters) throws Throwable { + MethodLink method = Links.getMethod(type, "getFlight", String.class); + FlightManagement management = parameters.get("flightManagement"); + Flight flight = parameters.get("flight"); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("Flight Management", management) + .add("flightNumber", flight.getFlightNumber()) + ).expect(builder -> builder + .cause(null) + .add("Result", "null") + ).build(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + System.setOut(new PrintStream(baos)); + AtomicReference result = new AtomicReference<>(); + Assertions2.call(() -> result.set(method.invoke(management, flight.getFlightNumber())), + info, + comment -> "Unexpected exception occurred while searching for the airport!" + ); + Assertions2.assertNull( + result.get(), + info, + comment -> "The result of the searched flight does not match the expected flight." + ); + String message = parameters.get("message"); + Assertions2.assertEquals( + message, baos.toString().trim(), + info, + comment -> "The output does not match the expected message." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_5_2_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_5_2_TestsPrivate.java new file mode 100644 index 0000000..03d1bbe --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_5_2_TestsPrivate.java @@ -0,0 +1,189 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Links; +import h08.mocks.FakeBookingManagement; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.mockito.Mockito; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.5.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.5.2 | Flight and Booking Management") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_5_2_TestsPrivate extends H08_Tests { + + + /** + * The converters used for the test cases using JSON files to read the test data. + */ + public static final Map> CONVERTERS = Map.of( + "flightManagement", JsonConverters::toFlightManagement, + "bookingManagement", JsonConverters::toBookingManagement, + "bookingId", node -> node.isNull() ? null : node.asText(), + "flightNumber", node -> node.isNull() ? null : node.asText(), + "passengerId", node -> node.isNull() ? null : node.asText(), + "airportCode", JsonNode::asText, + "flight", JsonConverters::toFlight, + "isAddOperation", JsonNode::asBoolean, + "expected", JsonConverters::toAirport + ); + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_2_validateAndCheckBookingDuplicate.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void validateAndCheckBookingDuplicate(JsonParameterSet parameters) throws Throwable { + TypeLink typeLink = Links.getType(BookingManagement.class); + MethodLink methodLink = Links.getMethod(typeLink, "validateAndCheckBooking", + String.class, String.class, String.class); + + BookingManagement management = parameters.get("bookingManagement"); + String bookingId = parameters.getString("bookingId"); + String flightNumber = parameters.getString("flightNumber"); + String passengerId = parameters.getString("passengerId"); + + ClassReference reference = ClassReference.DUPLICATE_BOOKING_EXCEPTION; + Class exceptionClass = (Class) reference.getLink().reflection(); + TestInformation info = TestInformation.builder() + .input(builder -> builder + .add("bookings", management) + .add("bookingId", bookingId) + .add("flightNumber", flightNumber) + .add("passengerId", passengerId) + ) + .expect(builder -> builder.cause(exceptionClass)) + .build(); + Exception exception = Assertions2.assertThrows( + exceptionClass, + () -> methodLink.invoke(management, bookingId, flightNumber, passengerId), + info, + comment -> "No exception thrown for invalid input." + ); + Assertions2.assertEquals( + "A booking with this ID already exists.", + exception.getMessage(), + info, + comment -> "Message does not match expected message." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_2_validateAndCheckBookingInvalid.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void validateAndCheckBookingInvalid(JsonParameterSet parameters) throws Throwable { + TypeLink typeLink = Links.getType(BookingManagement.class); + MethodLink methodLink = Links.getMethod(typeLink, "validateAndCheckBooking", + String.class, String.class, String.class); + + BookingManagement management = parameters.get("bookingManagement"); + String bookingId = parameters.get("bookingId"); + String flightNumber = parameters.get("flightNumber"); + String passengerId = parameters.get("passengerId"); + + ClassReference reference = ClassReference.INVALID_BOOKING_EXCEPTION; + Class exceptionClass = (Class) reference.getLink().reflection(); + TestInformation info = TestInformation.builder() + .input(builder -> builder + .add("bookings", management) + .add("bookingId", bookingId) + .add("flightNumber", flightNumber) + .add("passengerId", passengerId) + ) + .expect(builder -> builder.cause(exceptionClass)) + .build(); + Exception exception = Assertions2.assertThrows( + exceptionClass, + () -> methodLink.invoke(management, bookingId, flightNumber, passengerId), + info, + comment -> "No exception thrown for invalid input." + ); + Assertions2.assertEquals( + "Invalid booking details provided.", + exception.getMessage(), + info, + comment -> "Message does not match expected message." + ); + } + + @Test + void testManageFlightCode() throws Throwable { + FlightManagement management = Mockito.mock(FlightManagement.class, Mockito.CALLS_REAL_METHODS); + TypeLink airportLink = Links.getType(FlightManagement.class); + MethodLink manageFlightLink = Links.getMethod(airportLink, "manageFlight", String.class, Flight.class, boolean.class); + FieldLink airportsLink = Links.getField(airportLink, "airports"); + FieldLink sizeLink = Links.getField(airportLink, "size"); + Airport[] airports = new Airport[5]; + for (int i = 0; i < airports.length; i++) { + airports[i] = Mockito.mock(Airport.class); + Mockito.doReturn("Airport " + i).when(airports[i]).getAirportCode(); + } + airportsLink.set(management, airports); + sizeLink.set(management, airports.length); + + Flight flight = Mockito.mock(Flight.class); + Airport airport = airports[0]; + TestInformation info = TestInformation.builder() + .subject(manageFlightLink) + .input(builder -> builder + .add("airportCode", airport.getAirportCode()) + .add("flight", flight) + .add("isAddOperation", true)) + .build(); + Assertions2.call( + () -> management.manageFlight(airport.getAirportCode(), flight, true), + info, + comment -> "Unknown exception occurred while managing flight." + ); + Mockito.verify(airport, Mockito.times(1)).addFlight(Mockito.eq(flight), Mockito.anyBoolean()); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_2_testManageFlight.json", customConverters = CUSTOM_CONVERTERS) + void testManageFlight(JsonParameterSet parameters) throws Throwable { + FlightManagement management = parameters.get("flightManagement"); + String airportCode = parameters.get("airportCode"); + Flight flight = parameters.get("flight"); + boolean isAddOperation = parameters.get("isAddOperation"); + TestInformation info = TestInformation.builder() + .input(builder -> builder + .add("airportCode", airportCode) + .add("flight", flight) + .add("isAddOperation", isAddOperation)) + .build(); + management.manageFlight(airportCode, flight, isAddOperation); + FieldLink airportsLink = Links.getField(Links.getType(FlightManagement.class), "airports"); + Airport[] airports = airportsLink.get(management); + Airport actual = Arrays.stream(airports). + filter(it -> it.getAirportCode().equals(airportCode)) + .findFirst() + .orElseThrow(); + Airport expected = parameters.get("expected"); + Assertions2.assertEquals( + expected, + actual, + info, + comment -> "Airport does not match expected airport." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_5_3_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_5_3_TestsPrivate.java new file mode 100644 index 0000000..be47ce8 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_5_3_TestsPrivate.java @@ -0,0 +1,165 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Links; +import h08.mocks.FakeBookingManagement; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.5.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H8.5.3 | Searching a Booking") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_5_3_TestsPrivate extends H08_Tests { + + public static final Map> CONVERTERS = Map.of( + "bookingManagement", JsonConverters::toBookingManagement, + "booking", JsonConverters::toBooking + ); + + private TypeLink type; + + private PrintStream out; + + private PrintStream testOut; + + private ByteArrayOutputStream baos; + + @BeforeAll + protected void globalSetup() { + type = Links.getType(BookingManagement.class); + out = System.out; + } + + @BeforeEach + void setup() { + baos = new ByteArrayOutputStream(); + testOut = new PrintStream(baos); + System.setOut(testOut); + } + + @AfterAll + void globalTearDown() { + System.setOut(out); + } + + private void assertBooking(JsonParameterSet parameters, MethodLink method) throws Throwable { + BookingManagement management = parameters.get("bookingManagement"); + Booking booking = parameters.get("booking"); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("bookingManagement", management) + .add("bookingId", booking.getBookingId())) + .expect(builder -> builder.add("booking", booking)) + .build(); + AtomicReference result = new AtomicReference<>(); + Assertions2.call( + () -> result.set(method.invoke(management, booking.getBookingId())), + info, + comment -> "Unexpected exception occured while searching for booking." + ); + Assertions2.assertTrue( + TutorUtils.equalBookings(booking, result.get()), + info, + comment -> "The booking found is not the same as the expected booking." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_3_testSearchBooking.json", customConverters = CUSTOM_CONVERTERS) + void testSearchBooking(JsonParameterSet parameters) throws Throwable { + assertBooking(parameters, Links.getMethod(type, "searchBooking", String.class)); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_3_testSearchBookingException.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void testSearchBookingException(JsonParameterSet parameters) throws Throwable { + BookingManagement management = parameters.get("bookingManagement"); + Booking booking = parameters.get("booking"); + MethodLink method = Links.getMethod(type, "searchBooking", String.class); + ClassReference reference = ClassReference.BOOKING_NOT_FOUND_EXCEPTION; + Class exceptionClass = (Class) reference.getLink().reflection(); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("bookingManagement", management) + .add("bookingId", booking.getBookingId())) + .expect(builder -> builder.cause(exceptionClass)) + .build(); + Exception exception = Assertions2.assertThrows( + exceptionClass, + () -> method.invoke(management, booking.getBookingId()), + info, + comment -> "Expected exception was not thrown." + ); + String message = parameters.getString("message"); + Assertions2.assertEquals( + message, + exception.getMessage(), + info, + comment -> "Exception message does not match the expected message." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_3_testGetBooking.json", customConverters = CUSTOM_CONVERTERS) + void testGetBooking(JsonParameterSet parameters) throws Throwable { + assertBooking(parameters, Links.getMethod(type, "getBooking", String.class)); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_3_testGetBookingException.json", customConverters = CUSTOM_CONVERTERS) + void testGetBookingException(JsonParameterSet parameters) throws Throwable { + BookingManagement management = parameters.get("bookingManagement"); + Booking booking = parameters.get("booking"); + String message = parameters.getString("message"); + MethodLink method = Links.getMethod(type, "getBooking", String.class); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("bookingManagement", management) + .add("bookingId", booking.getBookingId()) + ) + .expect(builder -> builder.add("message", message)) + .build(); + Booking result = method.invoke(management, booking.getBookingId()); + Assertions2.assertNull( + result, + info, + comment -> "Expected null to be returned." + ); + + Assertions2.assertEquals( + message, + TutorUtils.cleanOutput(baos.toString()).trim(), + info, + comment -> "Printed message does not match the expected message." + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_5_4_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_5_4_TestsPrivate.java new file mode 100644 index 0000000..d05d902 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_5_4_TestsPrivate.java @@ -0,0 +1,141 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.Links; +import h08.mocks.FakeBookingManagement; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.5.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.5.4 | Cancelling a Booking") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_5_4_TestsPrivate extends H08_Tests { + + public static final Map> CONVERTERS = Map.of( + "bookingManagement", JsonConverters::toBookingManagement, + "booking", JsonConverters::toBooking + ); + + private MethodLink method; + + private PrintStream out; + + private PrintStream testOut; + + private ByteArrayOutputStream baos; + + @BeforeAll + protected void globalSetup() { + TypeLink type = Links.getType(BookingManagement.class); + method = Links.getMethod(type, "cancelBooking", String.class); + out = System.out; + } + + @BeforeEach + void setup() { + baos = new ByteArrayOutputStream(); + testOut = new PrintStream(baos); + System.setOut(testOut); + } + + @AfterEach + void tearDown() { + testOut.close(); + } + + /** + * Tears down the global test environment. + */ + @AfterAll + void globalTearDown() { + System.setOut(out); + } + + private void assertCancelBookingMessage(JsonParameterSet parameters) throws Throwable { + BookingManagement management = parameters.get("bookingManagement"); + Booking booking = parameters.get("booking"); + String message = parameters.getString("message"); + + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("management", management) + .add("bookingId", booking.getBookingId()) + ).expect(builder -> builder.add("message", message)) + .build(); + management.cancelBooking(booking.getBookingId()); + Assertions2.assertEquals( + message, + TutorUtils.cleanOutput(baos.toString()).trim(), + info, + comment -> "Printed message does not match expected message." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_4_testCancelBooking.json", customConverters = CUSTOM_CONVERTERS) + void testCancelBooking(JsonParameterSet parameters) throws Throwable { + FakeBookingManagement management = parameters.get("bookingManagement"); + Booking booking = Arrays.stream(management.getBookings()) + .filter(b -> TutorUtils.equalBookings(b, parameters.get("booking"))) + .findFirst() + .orElseThrow(); + String message = parameters.getString("message"); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("management", management) + .add("bookingId", booking.getBookingId()) + ).expect(builder -> builder.add("message", message)) + .build(); + management.cancelBooking(booking.getBookingId()); + Assertions2.assertTrue( + booking.isCancelled(), + info, + comment -> "Booking should be cancelled." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_4_testCancelBooking.json", customConverters = CUSTOM_CONVERTERS) + void testCancelBookingMessage(JsonParameterSet parameters) throws Throwable { + assertCancelBookingMessage(parameters); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_4_testCancelBookingAlreadyCancelled.json", customConverters = CUSTOM_CONVERTERS) + void testCancelBookingAlreadyCancelled(JsonParameterSet parameters) throws Throwable { + assertCancelBookingMessage(parameters); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_4_testCancelBookingNotFound.json", customConverters = CUSTOM_CONVERTERS) + void testCancelBookingNotFound(JsonParameterSet parameters) throws Throwable { + assertCancelBookingMessage(parameters); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_5_5_TestsPrivate.java b/solution/H08/src/graderPrivate/java/h08/H08_5_5_TestsPrivate.java new file mode 100644 index 0000000..bd6c654 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_5_5_TestsPrivate.java @@ -0,0 +1,201 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.ClassReference; +import h08.assertions.Links; +import h08.mocks.FakeBookingManagement; +import h08.rubric.context.TestInformation; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.mockito.Mockito; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for the subtask H08.5.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H08.5.5 | Creating a Booking") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H08_5_5_TestsPrivate extends H08_Tests { + + public static final Map> CONVERTERS = Map.of( + "bookingManagement", JsonConverters::toBookingManagement, + "booking", JsonConverters::toBooking + ); + + private MethodLink method; + + private PrintStream out; + + private PrintStream testOut; + + private ByteArrayOutputStream baos; + + @BeforeAll + protected void globalSetup() { + TypeLink type = Links.getType(BookingManagement.class); + method = Links.getMethod(type, "createBooking", String.class, String.class, String.class); + out = System.out; + } + + @BeforeEach + void setup() { + baos = new ByteArrayOutputStream(); + testOut = new PrintStream(baos); + System.setOut(testOut); + } + + @AfterEach + void tearDown() { + testOut.close(); + } + + /** + * Tears down the global test environment. + */ + @AfterAll + void globalTearDown() { + System.setOut(out); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_5_testCreateBooking.json", customConverters = CUSTOM_CONVERTERS) + void testCreateBooking(JsonParameterSet parameters) throws Throwable { + FakeBookingManagement management = parameters.get("bookingManagement"); + String bookingId = parameters.getString("bookingId"); + String flightNumber = parameters.getString("flightNumber"); + String passengerId = parameters.getString("passengerId"); + Booking booking = parameters.get("booking"); + + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("management", management) + .add("bookingId", bookingId) + .add("flightNumber", flightNumber) + .add("passengerId", passengerId)) + .build(); + management.createBooking(bookingId, flightNumber, passengerId); + Assertions2.assertTrue( + Arrays.stream(management.getBookings()).anyMatch(b -> TutorUtils.equalBookings(b, booking)), + info, + comment -> "Booking should be created." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_5_testCreateBooking.json", customConverters = CUSTOM_CONVERTERS) + @SuppressWarnings("unchecked") + void testCreateBookingNoFlight(JsonParameterSet parameters) throws Throwable { + FakeBookingManagement management = parameters.get("bookingManagement"); + FlightManagement flightManagement = management.getFlightManagement(); + String bookingId = parameters.getString("bookingId"); + String flightNumber = parameters.getString("flightNumber"); + String passengerId = parameters.getString("passengerId"); + String message = parameters.getString("message"); + Mockito.doReturn(null).when(flightManagement).getFlight(flightNumber); + ClassReference reference = ClassReference.FLIGHT_NOT_FOUND_EXCEPTION; + Class exceptionClass = (Class) reference.getLink().reflection(); + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("management", management) + .add("bookingId", bookingId) + .add("flightNumber", flightNumber) + .add("passengerId", passengerId)) + .expect(builder -> builder + .cause(exceptionClass) + .add("Message", message)) + .build(); + Exception exception = Assertions2.assertThrows( + exceptionClass, + () -> management.createBooking(bookingId, flightNumber, passengerId), + info, + comment -> "Should throw a FlightNotFoundException." + ); + Assertions2.assertEquals( + message, + exception.getMessage(), + info, + comment -> "The message should be correct." + ); + } + + private void assertCreateBookingMessage(JsonParameterSet parameters) throws Throwable { + BookingManagement management = parameters.get("bookingManagement"); + String bookingId = parameters.getString("bookingId"); + String flightNumber = parameters.getString("flightNumber"); + String passengerId = parameters.getString("passengerId"); + String message = parameters.getString("message"); + + TestInformation info = TestInformation.builder() + .subject(method) + .input(builder -> builder + .add("management", management) + .add("bookingId", bookingId) + .add("flightNumber", flightNumber) + .add("passengerId", passengerId)) + .expect(builder -> builder.add("Message", message)) + .build(); + management.createBooking(bookingId, flightNumber, passengerId); + Assertions2.assertEquals( + message, + TutorUtils.cleanOutput(baos.toString()).trim(), + info, + comment -> "Printed message does not match expected message." + ); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_5_testCreateBookingDuplicate.json", customConverters = CUSTOM_CONVERTERS) + void testCreateBookingDuplicate(JsonParameterSet parameters) throws Throwable { + assertCreateBookingMessage(parameters); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_5_testCreateBookingInvalid.json", customConverters = CUSTOM_CONVERTERS) + void testCreateBookingInvalid(JsonParameterSet parameters) throws Throwable { + assertCreateBookingMessage(parameters); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_5_testCreateBookingNoSeats.json", customConverters = CUSTOM_CONVERTERS) + void testCreateBookingNoSeats(JsonParameterSet parameters) throws Throwable { + assertCreateBookingMessage(parameters); + } + + @ParameterizedTest + @JsonParameterSetTest(value = "H08_5_5_testCreateBookingValidation.json", customConverters = CUSTOM_CONVERTERS) + void testCreateBookingValidation(JsonParameterSet parameters) throws Throwable { + FakeBookingManagement management = parameters.get("bookingManagement"); + FlightManagement flightManagement = management.getFlightManagement(); + String bookingId = parameters.getString("bookingId"); + String flightNumber = parameters.getString("flightNumber"); + String passengerId = parameters.getString("passengerId"); + Flight flight = Mockito.mock(Flight.class); + Mockito.doReturn(flightNumber).when(flight).getFlightNumber(); + Mockito.doReturn(flight).when(flightManagement).getFlight(flightNumber); + management.createBooking(bookingId, flightNumber, passengerId); + Mockito.verify(flight, Mockito.times(1)).bookSeat(); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_RubricProvider.java b/solution/H08/src/graderPrivate/java/h08/H08_RubricProvider.java new file mode 100644 index 0000000..872c1ec --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_RubricProvider.java @@ -0,0 +1,226 @@ +package h08; + +import h08.rubric.TaskRubricProvider; +import h08.rubric.task.AtomicTask; +import h08.rubric.task.CompositeTask; +import h08.rubric.task.Subtask; +import h08.rubric.task.Task; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; + +import java.util.List; +import java.util.Map; + +/** + * Provides the rubrics for H08. + * + * @author Nhan Huynh + */ +public class H08_RubricProvider extends TaskRubricProvider { + + /** + * Defines the rubric for task H08.1. + */ + private static final Task H08_1 = AtomicTask.builder() + .description("H08.1 | Have your ID ready") + .testClassName("h08.H08_1_Tests") + .criterion("Die Methode generatePassengerID stellt sicher, dass die ersten zwei Zeichen der ID die Initialen des Vornamens und Nachnamens sind.", "testGeneratePassengerIDNameInitials", JsonParameterSet.class) + .criterion("Die Methode generatePassengerID stellt sicher, dass der Hash-Code des Datums korrekt im zweiten Teil der ID enthalten ist.", "testGeneratePassengerIDDateHash", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for subtask H08.2.1 + */ + private static final Subtask H08_2_1 = Subtask.builder() + .description("H8.2.1 | Let’s get in shape.") + .testClassName("h08.H08_2_1_Tests") + .criterion("Die Methode validateFlightNumber überprüft die Flugnummer korrekt.", Map.of( + "testValidateFlightNumber", List.of(), + "testValidateFlightNumberException", List.of(JsonParameterSet.class) + )) + .criterion("Der Konstruktor der Klasse Flight enthält assert-Anweisungen, die die Eingaben überprüfen.", Map.of( + "testFlightConstructor", List.of(), + "testFlightConstructorException", List.of(JsonParameterSet.class) + )) + .build(); + + /** + * Defines the rubric for subtask H08.2.2 + */ + private static final Subtask H08_2_2 = Subtask.builder() + .description("H08.2.2 | Fasten your seatbelts") + .testClassName("h08.H08_2_2_Tests") + .criterion("Die Methode bookSeat() reserviert korrekt Sitzplätze.", "testBookSeat", JsonParameterSet.class) + .criterion("Die Methode wirft korrekt eine NoSeatsAvailableException, wenn keine Plätze mehr verfügbar sind.", Map.of( + "testNoSeatsAvailableException", List.of(), + "testBookSeatException", List.of() + )) + .build(); + + /** + * Defines the rubric for task H08.2. + */ + private static final Task H08_2 = CompositeTask.builder() + .description("H08.2 | Flight Zone") + .subtasks(H08_2_1, H08_2_2) + .build(); + + /** + * Defines the rubric for task H08.3. + */ + private static final Task H08_3 = AtomicTask.builder() + .description("H08.3 | Exception Handling") + .testClassName("h08.H08_3_Tests") + .criterion("Die FlightManagementException ist korrekt implementiert.", "testFlightManagementException") + .criterion("Die BookingManagementException ist korrekt implementiert.", "testBookingManagementException") + .criterion("Die FlightNotFoundException, BookingNotFoundException und InvalidBookingException sind korrekt.", Map.of( + "testFlightNotFoundException", List.of(), + "testBookingNotFoundException", List.of(), + "testInvalidBookingException", List.of()) + ) + .criterion("Die BookingAlreadyCancelledException und DuplicateBookingException sind korrekt.", Map.of( + "testBookingAlreadyCancelledException", List.of(), + "testDuplicateBookingException", List.of()) + ).build(); + + /** + * Defines the rubric for subtask H08.4.1. + */ + private static final Subtask H08_4_1 = Subtask.builder() + .description("H08.4.1 | Adding a Flight") + .testClassName("h08.H08_4_1_Tests") + .criterion("Die Methode addFlight fügt Flüge korrekt zu abgehenden oder ankommenden Flügen hinzu.", "testAddFlight", JsonParameterSet.class) + .criterion("Die Methode prüft und behandelt korrekt falsche Flughafencodes.", "testAddFlightException", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for subtask H08.4.2. + */ + private static final Subtask H08_4_2 = Subtask.builder() + .description("H08.4.2 | Removing a Flight") + .testClassName("h08.H08_4_2_Tests") + .criterion("Die Methode removeFlight entfernt Flüge korrekt aus den Listen.", "testRemoveFlight", JsonParameterSet.class) + .criterion("Die Methode wirft korrekt eine FlightNotFoundException, wenn der Flug nicht gefunden wird.", "testRemoveFlightException", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for subtask H08.4.3. + */ + private static final Subtask H08_4_3 = Subtask.builder() + .description("H08.4.3 | Getting a Flight") + .testClassName("h08.H08_4_3_Tests") + .criterion("Die Methode getFlight gibt Flüge korrekt zurück.", "testGetFlight", JsonParameterSet.class) + .criterion("Die Methode wirft korrekt eine FlightNotFoundException, wenn der Flug nicht existiert.", "testGetFlightException", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for subtask H08.4.4. + */ + private static final Subtask H08_4_4 = Subtask.builder() + .description("H08.4.4 | Removing a booking") + .testClassName("h08.H08_4_4_Tests") + .criterion("Die Methode cancelBooking() storniert eine Buchung korrekt.", "testCancelBooking", JsonParameterSet.class) + .criterion("Die Methode wirft korrekt eine BookingAlreadyCancelledException, wenn die Buchung bereits storniert wurde.", "testCancelBookingException", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for task H08.4. + */ + private static final Task H08_4 = CompositeTask.builder() + .description("H08.4 | Airport Command Center") + .subtasks(H08_4_1, H08_4_2, H08_4_3, H08_4_4) + .build(); + + /** + * Defines the rubric for subtask H08.5.1. + */ + private static final Subtask H08_5_1 = Subtask.builder() + .description("H8.5.1 | Airport and Flight Lookup") + .testClassName("h08.H08_5_1_Tests") + .criterion("Die Methode searchAirport findet Flughäfen korrekt.", Map.of( + "testSearchAirport", List.of(JsonParameterSet.class), + "testSearchAirportException", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode searchFlight durchsucht Flüge korrekt.", "testSearchFlight", JsonParameterSet.class) + .criterion("Die Methode getFlight gibt Flüge korrekt zurück.", Map.of( + "testGetFlight", List.of(JsonParameterSet.class), + "testGetFlightNull", List.of(JsonParameterSet.class) + )) + .build(); + + /** + * Defines the rubric for subtask H08.5.2. + */ + private static final Subtask H08_5_2 = Subtask.builder() + .description("H08.5.2 | Flight and Booking Management") + .testClassName("h08.H08_5_2_Tests") + .criterion("Die Methode manageFlight verwaltet Flüge korrekt (Hinzufügen oder Entfernen).", "testManageFlight", JsonParameterSet.class) + .criterion("Die Methode manageFlight prüft korrekt die Flughafencodes.", "testManageFlightCode") + .criterion("Die Methode validateAndCheckBooking validiert Buchungsdetails korrekt.", "validateAndCheckBookingInvalid", JsonParameterSet.class) + .criterion("Die Methode validateAndCheckBooking prüft korrekt auf doppelte Buchungen.", "validateAndCheckBookingDuplicate", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for subtask H08.5.3. + */ + private static final Subtask H08_5_3 = Subtask.builder() + .description("H8.5.3 | Searching a Booking") + .testClassName("h08.H08_5_3_Tests") + .criterion("Die Methode searchBooking durchsucht Buchungen korrekt.", Map.of( + "testSearchBooking", List.of(JsonParameterSet.class), + "testSearchBookingException", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode getBooking gibt Buchungen korrekt zurück.", Map.of( + "testGetBooking", List.of(JsonParameterSet.class), + "testGetBookingException", List.of(JsonParameterSet.class) + )) + .build(); + + /** + * Defines the rubric for subtask H08.5.4. + */ + private static final Subtask H08_5_4 = Subtask.builder() + .description("H08.5.4 | Cancelling a Booking") + .testClassName("h08.H08_5_4_Tests") + .criterion("Die Methode cancelBooking storniert Buchungen korrekt.", "testCancelBooking", JsonParameterSet.class) + .criterion("Die Methode gibt die richtigen Fehlermeldungen oder Bestätigungen aus.", Map.of( + "testCancelBookingMessage", List.of(JsonParameterSet.class), + "testCancelBookingAlreadyCancelled", List.of(JsonParameterSet.class), + "testCancelBookingNotFound", List.of(JsonParameterSet.class) + )) + .build(); + + /** + * Defines the rubric for subtask H08.5.5. + */ + private static final Subtask H08_5_5 = Subtask.builder() + .description("H08.5.5 | Creating a Booking") + .testClassName("h08.H08_5_5_Tests") + .criterion("Die Methode createBooking erstellt Buchungen korrekt.", "testCreateBooking", JsonParameterSet.class) + .criterion("Die Methode behandelt alle relevanten Ausnahmen korrekt.", Map.of( + "testCreateBookingDuplicate", List.of(JsonParameterSet.class), + "testCreateBookingInvalid", List.of(JsonParameterSet.class), + "testCreateBookingNoSeats", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode validiert Buchungsdetails und reserviert Sitzplätze korrekt.", "testCreateBookingValidation", JsonParameterSet.class) + .build(); + + /** + * Defines the rubric for task H08.5. + */ + private static final Task H08_5 = CompositeTask.builder() + .description("H08.5 | Booking and Flight Management") + .subtasks(H08_5_1, H08_5_2, H08_5_3, H08_5_4, H08_5_5) + .build(); + + /** + * Creates a new rubric provider for H08. + */ + public H08_RubricProvider() { + super(8, "Flight Control: Navigating the Exceptions", true); + } + + @Override + public List getTasks() { + return List.of(H08_1, H08_2, H08_3, H08_4, H08_5); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/H08_Tests.java b/solution/H08/src/graderPrivate/java/h08/H08_Tests.java new file mode 100644 index 0000000..a183af6 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/H08_Tests.java @@ -0,0 +1,113 @@ +package h08; + +import h08.assertions.ClassReference; +import h08.rubric.context.TestInformation; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.opentest4j.AssertionFailedError; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.callable.Callable; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.ConstructorLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.List; + +/** + * Defines a test skeleton for the H08 assignment. + * + *

Use the following schema: + *

{@code
+ *     public class TestClass extends H08_Test {
+ *
+ *          public static final Map> CUSTOM_CONVERTERS = Map.of(
+ *              ...
+ *          );
+ *
+ *          @ParameterizedTest
+ *          @JsonParameterSetTest(value = "path-to-json-data.json", customConverters = CUSTOM_CONVERTERS)
+ *          void testXYZ(JsonParameterSet parameters) {
+ *              ...
+ *          }
+ *   }
+ * }
+ * + * @author Nhan Huynh + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@TestForSubmission +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public abstract class H08_Tests { + + /** + * The attribute name for custom converters in the JSON parameter set test annotation. + */ + public static final String CUSTOM_CONVERTERS = "CONVERTERS"; + + @BeforeAll + protected void globalSetup() { + Assertions.assertNotNull( + getClass().getAnnotation(TestForSubmission.class), + "The test class is not annotated with @TestForSubmission which is needed for Jagr to work" + ); + } + + /** + * Asserts that the given exception class reference is defined correctly. This method checks if the class reference + * is correctly defined and if a constructor with a single {@link String} parameter is defined. + * + * @param reference the exception class reference to check + */ + public void assertExceptionDefinedCorrectly(ClassReference reference) { + reference.assertCorrectlyDefined(); + List constructorParameterTypes = List.of(BasicTypeLink.of(String.class)); + TypeLink typeLink = reference.getLink(); + ConstructorLink constructorLink = typeLink.getConstructor( + Matcher.of(c -> c.typeList().equals(constructorParameterTypes)) + ); + TestInformation info = TestInformation.builder() + .subject(typeLink) + .expect(builder -> builder + .add("Constructor", "Constructor with parameters %s".formatted(constructorParameterTypes))) + .actual(builder -> builder.add("Constructor", constructorLink)) + .build(); + Assertions2.assertNotNull( + constructorLink, + info, + comment -> "Could not find constructor with parameters %s".formatted(constructorParameterTypes) + ); + } + + /** + * Asserts that the given callable throws an assertion error. + * + * @param callable the callable to call and check + * @param context the context information about the test case + * + * @throws AssertionFailedError if the callable does not throw an assertion error + */ + @SuppressWarnings("ConstantConditions") + public void assertAssertions(Callable callable, Context context) { + @Nullable Throwable throwable = null; + try { + callable.call(); + } catch (AssertionError e) { + throwable = e; + } catch (Throwable e) { + Assertions2.fail(context, comment -> "Unexpected exception thrown: %s".formatted(e)); + } + + Assertions2.assertNotNull(throwable, context, comment -> "Expected an assertion to be thrown, but none was thrown."); + Assertions2.assertEquals( + AssertionError.class, + throwable.getClass(), + context, + comment -> "Exception type does not match AssertionError."); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/JsonConverters.java b/solution/H08/src/graderPrivate/java/h08/JsonConverters.java new file mode 100644 index 0000000..64e0739 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/JsonConverters.java @@ -0,0 +1,166 @@ +package h08; + +import com.fasterxml.jackson.databind.JsonNode; +import h08.assertions.Mocks; +import h08.mocks.FakeAirport; +import h08.mocks.FakeBookingManagement; +import org.jetbrains.annotations.Nullable; +import org.mockito.Mockito; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +/** + * Defines JSON converters for the H08 assignment. + * + * @author Nhan Huynh + */ +public final class JsonConverters extends org.tudalgo.algoutils.tutor.general.json.JsonConverters { + + /** + * The date formatter for the date of birth. + */ + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + /** + * The date time formatter for the departure time. + */ + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + + /** + * Prevent instantiation of this utility class. + */ + private JsonConverters() { + } + + /** + * Converts a JSON node to a local date. + * + * @param node the JSON node to convert + * + * @return the local date represented by the JSON node + */ + public static LocalDate toLocalDate(JsonNode node) { + if (!node.isTextual()) { + throw new IllegalArgumentException("Expected a textual value"); + } + return LocalDate.parse(node.asText(), DATE_FORMATTER); + } + + /** + * Converts a JSON node to a local date time. + * + * @param node the JSON node to convert + * + * @return the local date time represented by the JSON node + */ + public static LocalDateTime toLocalDateTime(JsonNode node) { + if (!node.isTextual()) { + throw new IllegalArgumentException("Expected a textual value"); + } + return LocalDateTime.parse(node.asText(), DATE_TIME_FORMATTER); + } + + /** + * Converts a JSON node to a flight. + * + * @param node the JSON node to convert + * + * @return the flight represented by the JSON node + */ + public static @Nullable Flight toFlight(JsonNode node) { + if (node.isNull()) { + return null; + } + if (!node.isObject()) { + throw new IllegalArgumentException("Node is not an object"); + } + return Mocks.createFlight( + node.get("flightNumber").asText(), + node.get("departure").asText(), + node.get("destination").asText(), + toLocalDateTime(node.get("departureTime")), + node.get("initialSeats").asInt(), + node.get("availableSeats").asInt() + ); + } + + /** + * Converts a JSON node to an airport. + * + * @param node the JSON node to convert + * + * @return the airport represented by the JSON node + */ + public static Airport toAirport(JsonNode node) { + if (!node.isObject()) { + throw new IllegalArgumentException("Node is not an object"); + } + return new FakeAirport( + node.get("airportCode").asText(), + node.get("initialCapacity").asInt(), + toList(node.get("departingFlights"), JsonConverters::toFlight).toArray(Flight[]::new), + toList(node.get("arrivingFlights"), JsonConverters::toFlight).toArray(Flight[]::new), + node.get("departingSize").asInt(), + node.get("arrivingSize").asInt() + ); + } + + /** + * Converts a JSON node to a booking. + * + * @param node the JSON node to convert + * + * @return the booking represented by the JSON node + */ + public static Booking toBooking(JsonNode node) { + if (!node.isObject()) { + throw new IllegalArgumentException("Expected an object"); + } + String bookingId = node.get("bookingId").asText(); + String flightNumber = node.get("flightNumber").asText(); + String passengerId = node.get("passengerId").asText(); + Booking booking = new Booking(bookingId, flightNumber, passengerId); + if (node.has("isCancelled")) { + boolean isCancelled = node.get("isCancelled").asBoolean(); + FieldLink isCancelledLink = BasicTypeLink.of(Booking.class) + .getField(Matcher.of(field -> field.name().equals("isCancelled"))); + isCancelledLink.set(booking, isCancelled); + } + return booking; + } + + /** + * Converts a JSON node to a flight management. + * + * @param node the JSON node to convert + * + * @return the flight management represented by the JSON node + */ + public static FlightManagement toFlightManagement(JsonNode node) { + if (!node.isObject()) { + throw new IllegalArgumentException("Expected an object"); + } + List airports = toList(node.get("airports"), JsonConverters::toAirport); + FlightManagement instance = new FlightManagement(airports.size()); + for (Airport airport : airports) { + instance.addAirport(airport); + } + return instance; + } + + public static FakeBookingManagement toBookingManagement(JsonNode node) { + if (!node.isObject()) { + throw new IllegalArgumentException("Expected an object"); + } + return new FakeBookingManagement( + node.has("flightManagement") ? toFlightManagement(node.get("flightManagement")) : Mockito.mock(FlightManagement.class), + toList(node.get("bookings"), JsonConverters::toBooking) + ); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/TestConstants.java b/solution/H08/src/graderPrivate/java/h08/TestConstants.java new file mode 100644 index 0000000..57481f4 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/TestConstants.java @@ -0,0 +1,38 @@ +package h08; + +import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers; +import org.tudalgo.algoutils.tutor.general.match.MatcherFactories; + +/** + * Constants for tests for configuring test behavior. + * + * @author Nhan Huynh + */ +public final class TestConstants { + + /** + * Timeout for tests in seconds. + */ + public static final int TEST_TIMEOUT_IN_SECONDS = 2; + + /** + * Skip after the first failed test. + */ + public static final boolean SKIP_AFTER_FIRST_FAILED_TEST = true; + + /** + * Minimum similarity for string matching. + */ + public static final double MINIMUM_SIMILARITY = .75; + + /** + * Matcher factory for string matchers. + */ + public static final MatcherFactories.StringMatcherFactory STRING_MATCHER_FACTORY = BasicStringMatchers::identical; + + /** + * Prevent instantiation of this utility class. + */ + private TestConstants() { + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/TutorUtils.java b/solution/H08/src/graderPrivate/java/h08/TutorUtils.java new file mode 100644 index 0000000..dbfc61f --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/TutorUtils.java @@ -0,0 +1,91 @@ +package h08; + +import h08.assertions.Links; +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Objects; + +/** + * Tutor specific utility related to this assignment. + */ +public final class TutorUtils { + + /** + * Prevent instantiation of this utility class. + */ + private TutorUtils() { + } + + /** + * Returns {@code true} if the two flights are equal, {@code false} otherwise. This method compares the flight + * since the {@link Flight#equals(Object)} method is not implemented. Use this method to compare two flights. + * + * @param flight1 the first flight to compare + * @param flight2 the second flight to compare + * + * @return {@code true} if the two flights are equal, {@code false} otherwise + */ + public static boolean equalFlight(Flight flight1, Flight flight2) { + if (flight1 == null || flight2 == null) { + return flight1 == flight2; + } + TypeLink typeLink = Links.getType(Flight.class); + FieldLink initialSeatsLink = typeLink.getField(Matcher.of(field -> field.name().equals("initialSeats"))); + return Objects.equals(flight1.getFlightNumber(), flight2.getFlightNumber()) + && Objects.equals(flight1.getDepartureTime(), flight2.getDepartureTime()) + && Objects.equals(flight1.getDestination(), flight2.getDestination()) + && Objects.equals(initialSeatsLink.get(flight1), initialSeatsLink.get(flight2)) + && Objects.equals(flight1.getAvailableSeats(), flight2.getAvailableSeats()); + } + + /** + * Returns {@code true} if the two arrays of flights are equal, {@code false} otherwise. This method compares the + * + * @param flights1 the first array of flights + * @param flights2 the second array of flights + * + * @return {@code true} if the two arrays of flights are equal, {@code false} otherwise + * @see #equalFlight(Flight, Flight) + */ + public static boolean equalFlights(Flight[] flights1, Flight[] flights2) { + if (flights1.length != flights2.length) { + return false; + } + for (int i = 0; i < flights1.length; i++) { + @Nullable Flight flight1 = flights1[i]; + @Nullable Flight flight2 = flights2[i]; + if (flight1 == null && flight2 == null) { + continue; + } + if (flight1 == null || flight2 == null) { + return false; + } + if (!equalFlight(flight1, flight2)) { + return false; + } + } + return true; + } + + public static boolean equalBookings(Booking booking1, Booking booking2) { + return Objects.equals(booking1.getBookingId(), booking2.getBookingId()) + && Objects.equals(booking1.getFlightNumber(), booking2.getFlightNumber()) + && Objects.equals(booking1.getPassengerId(), booking2.getPassengerId()) + && booking1.isCancelled() == booking2.isCancelled(); + } + + public static String cleanOutput(String output) { + String[] lines = output.split("\n"); + StringBuilder actual = new StringBuilder(); + + for (String line : lines) { + if (!line.contains("Mockito")) { + actual.append(line).append("\n"); + } + } + return actual.toString(); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/assertions/ClassReference.java b/solution/H08/src/graderPrivate/java/h08/assertions/ClassReference.java new file mode 100644 index 0000000..432ba76 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/assertions/ClassReference.java @@ -0,0 +1,337 @@ +package h08.assertions; + + +import h08.rubric.context.TestInformation; +import org.jetbrains.annotations.Nullable; +import org.opentest4j.AssertionFailedError; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.Link; +import org.tudalgo.algoutils.tutor.general.reflections.Modifier; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertArrayEquals; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals; +import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue; + +/** + * A class reference represents a reference to a class in the project which may or may not be defined. It provides + * operations to assert the existence and correctness of the class. + * + * @author
h07.ClassReference + */ +public class ClassReference { + + /** + * The predefined packages in this assignment. + */ + public static final List PREDEFINED_PACKAGES = List.of("h08", "h08.Exceptions", "Exceptions"); + + /** + * The class reference for the NoSeatsAvailableException class. + */ + public static final ClassReference NO_SEATS_AVAILABLE_EXCEPTION = new ClassReference( + "h08", + "NoSeatsAvailableException", + new String[]{Exception.class.getSimpleName()}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the FlightManagementException class. + */ + public static final ClassReference FLIGHT_MANAGEMENT_EXCEPTION = new ClassReference( + "h08", + "FlightManagementException", + new String[]{Exception.class.getSimpleName()}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the BookingManagementException class. + */ + public static final ClassReference BOOKING_MANAGEMENT_EXCEPTION = new ClassReference( + "h08", + "BookingManagementException", + new String[]{Exception.class.getSimpleName()}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the FlightNotFoundException class. + */ + public static final ClassReference FLIGHT_NOT_FOUND_EXCEPTION = new ClassReference( + "h08", + "FlightNotFoundException", + new String[]{"FlightManagementException"}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the BookingNotFoundException class. + */ + public static final ClassReference BOOKING_NOT_FOUND_EXCEPTION = new ClassReference( + "h08", + "BookingNotFoundException", + new String[]{"BookingManagementException"}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the InvalidBookingException class. + */ + public static final ClassReference INVALID_BOOKING_EXCEPTION = new ClassReference( + "h08", + "InvalidBookingException", + new String[]{"BookingManagementException"}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the BookingAlreadyCancelledException class. + */ + public static final ClassReference BOOKING_ALREADY_CANCELLED_EXCEPTION = new ClassReference( + "h08", + "BookingAlreadyCancelledException", + new String[]{"FlightNotFoundException"}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The class reference for the DuplicateBookingException class. + */ + public static final ClassReference DUPLICATE_BOOKING_EXCEPTION = new ClassReference( + "h08", + "DuplicateBookingException", + new String[]{"InvalidBookingException"}, + Link.Kind.CLASS, + Modifier.PUBLIC, + Modifier.NON_FINAL, + Modifier.NON_ABSTRACT + ); + + /** + * The package name of the class. + */ + private final String packageName; + + /** + * The class name of the class. + */ + private final String className; + + private final String[] superClassNames; + + /** + * The kind of the class. + */ + private final Link.Kind kind; + + /** + * The modifiers of the class. + */ + private final Modifier[] modifiers; + + /** + * The link to the class. + */ + private @Nullable BasicTypeLink link; + + /** + * Creates a new class reference with the given package name, class name, super classes and kind. + * + * @param packageName the package name of the class + * @param className the class name of the class + * @param superClassNames the super class names of the class + * @param kind the kind of the class + */ + public ClassReference(String packageName, String className, String[] superClassNames, Link.Kind kind) { + this(packageName, className, superClassNames, kind, new Modifier[0]); + } + + /** + * Creates a new class reference with the given package name, class name, super classes, kind and modifiers. + * + * @param packageName the package name of the class + * @param className the class name of the class + * @param superClassNames the super class names of the class + * @param kind the kind of the class + * @param modifiers the modifiers of the class + */ + public ClassReference(String packageName, String className, String[] superClassNames, Link.Kind kind, Modifier... modifiers) { + this.packageName = packageName; + this.className = className; + this.superClassNames = superClassNames; + this.kind = kind; + this.modifiers = modifiers; + + try { + for (String predefinedPackageName : PREDEFINED_PACKAGES) { + link = (BasicTypeLink) BasicPackageLink.of(predefinedPackageName).getType(Matchers.matchString(className)); + if (link != null && !link.reflection().getName().endsWith("Test")) { + return; + } + } + link = null; + + } catch (Exception ignored) { + } + } + + /** + * Returns the class name of the class. + * + * @return the class name of the class + */ + public String getClassName() { + return className; + } + + /** + * Returns {@code true} if the class is defined, {@code false} otherwise. + * + * @return {@code true} if the class is defined, {@code false} otherwise + */ + public boolean isDefined() { + return link != null; + } + + /** + * Asserts that the class is defined (exists). + * + * @throws AssertionFailedError if the class is not defined + */ + public void assertDefined() { + TestInformation info = TestInformation.builder() + .subject(link) + .expect(builder -> builder + .add("Package", packageName) + .add("Name", className) + .add("Kind", kind) + .add("Modifier", Arrays.stream(modifiers) + .map(Modifier::keyword) + .collect(Collectors.joining(", ")))) + .build(); + assertTrue( + isDefined(), + info, + comment -> "Could not find class %s. Class is not defined or could not be found.".formatted(className) + ); + } + + /** + * Returns the test information for this class reference. + * + * @return the test information for this class reference + */ + public TestInformation info() { + assert link != null; + return TestInformation.builder() + .subject(link) + .expect(builder -> builder + .add("Package", packageName) + .add("Name", className) + .add("Kind", kind) + .add("Modifier", Arrays.stream(modifiers) + .map(Modifier::keyword) + .toList())) + .actual(builder -> builder + .add("Package", link.reflection().getPackage().getName()) + .add("Name", link.name()) + .add("Kind", link.kind()) + .add("Modifier", Arrays.stream(Modifier.fromInt(link.modifiers())) + .map(Modifier::keyword) + .toList())) + .build(); + } + + /** + * Asserts that the class is correctly defined with all its specifications. + * + * @throws AssertionFailedError if the class is not defined or the specifications do not match + */ + public void assertCorrectlyDefined() { + assertDefined(); + assert link != null; + TestInformation info = info(); + assertEquals(kind, link.kind(), info, comment -> "Kind does not match expected kind."); + assertTrue( + Arrays.stream(modifiers).allMatch(m -> m.is(link.modifiers())), + info, + r -> "The modifiers of the type do not match the expected modifiers." + ); + String[] actualSuperClassNames = Stream.concat(Stream.of(link.superType()), link.interfaces().stream()) + .map(type -> type.reflection().getSimpleName()) + .toArray(String[]::new); + assertArrayEquals( + superClassNames, + actualSuperClassNames, + info, + comment -> "The super classes of the type do not match the expected super classes."); + } + + /** + * Asserts that the class is named correctly. + * + * @throws AssertionFailedError if the class is not defined or the name does not match the expected name + */ + public void assertNamedCorrectly() { + if (!isDefined()) { + return; + } + assert link != null; + assertEquals(className, link.name(), info(), r -> "The name of the Type does not match the expected name."); + } + + /** + * Asserts that the class is defined in the correct package. + * + * @throws AssertionFailedError if the class is not defined or the package does not match the expected package + */ + public void assertDefinedInCorrectPackage() { + assertDefined(); + assert link != null; + assertEquals( + packageName.toLowerCase(), + link.reflection().getPackage().getName().toLowerCase(), + info(), + comment -> "Package name does not match expected package name." + ); + } + + /** + * Returns the link to the class. + * + * @return the link to the class + * @throws AssertionFailedError if the class is not defined + */ + public BasicTypeLink getLink() { + assertDefined(); + return link; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/assertions/Links.java b/solution/H08/src/graderPrivate/java/h08/assertions/Links.java new file mode 100644 index 0000000..d32421f --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/assertions/Links.java @@ -0,0 +1,136 @@ +package h08.assertions; + +import h08.TestConstants; +import org.opentest4j.AssertionFailedError; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions3; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; +import java.util.List; + +/** + * Provides utility methods for obtaining links to classes, fields, and methods for an assignment. + * + * @author Nhan Huynh + */ +public final class Links { + + /** + * Prevent instantiation of this utility class. + */ + private Links() { + } + + /** + * Returns the link to the class with the given name in the given package. + * + * @param packageName the package name of the class + * @param className the name of the class + * + * @return the link to the class with the given name + * @throws AssertionFailedError if the class could not be found + */ + public static TypeLink getType(String packageName, String className) { + try { + return Assertions3.assertTypeExists( + BasicPackageLink.of(packageName), + TestConstants.STRING_MATCHER_FACTORY.matcher(className) + ); + } catch (AssertionFailedError e) { + // Only execute this if the class is not a project class e.g. stdlib class + try { + return BasicTypeLink.of(Class.forName(packageName + "." + className)); + } catch (ClassNotFoundException ex) { + throw e; + } + } + } + + /** + * Returns the link to the class. + * + * @param clazz the class to get the link for + * + * @return the link to the class + * @throws AssertionFailedError if the class could not be found + */ + public static TypeLink getType(Class clazz) { + return getType(clazz.getPackageName(), clazz.getSimpleName()); + } + + /** + * Returns the link to the field with the given name in the given class. + * + * @param type the link to the class to get the field from + * @param methodName the name of the field to get + * @param matchers the matchers to apply to the field which must all match + * + * @return the link to the field with the given name in the given class + * @throws AssertionFailedError if the field could not be retrieved + */ + @SafeVarargs + public static FieldLink getField(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertFieldExists( + type, + Arrays.stream(matchers) + .reduce(TestConstants.STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the link to the method with the given name in the given class. + * + * @param type the link to the class to get the method from + * @param methodName the name of the method to get + * @param matchers the matchers to apply to the method which must all match + * + * @return the link to the method with the given name in the given class + * @throws AssertionFailedError if the method could not be retrieved + */ + @SafeVarargs + public static MethodLink getMethod(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertMethodExists( + type, + Arrays.stream(matchers).reduce(TestConstants.STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the link to the method with the given name and parameter types in the given class. + * + * @param type the link to the class to get the method from + * @param methodName the name of the method to get + * @param parameterTypes the parameter types of the method to get + * + * @return the link to the method with the given name and parameter types in the given class + * @throws AssertionFailedError if the method could not be retrieved + */ + public static MethodLink getMethod(TypeLink type, String methodName, Class... parameterTypes) { + List> parameters = Arrays.stream(parameterTypes).toList(); + return getMethod( + type, + methodName, + Matcher.of(method -> method.typeList().stream() + .map(TypeLink::reflection) + .toList() + .equals(parameters)) + ); + } + + /** + * Returns the link to the method with the given name in the given class. + * + * @param type the class to get the method from + * @param methodName the name of the method to get + * + * @return the link to the method with the given name in the given class + */ + public static MethodLink getMethod(TypeLink type, String methodName) { + return getMethod(type, methodName, new Class[0]); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/assertions/Matchers.java b/solution/H08/src/graderPrivate/java/h08/assertions/Matchers.java new file mode 100644 index 0000000..b69b211 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/assertions/Matchers.java @@ -0,0 +1,65 @@ +package h08.assertions; + +import h08.TestConstants; +import org.tudalgo.algoutils.tutor.general.match.Match; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.match.MatchingUtils; +import org.tudalgo.algoutils.tutor.general.match.Stringifiable; + +/** + * Utility class for creating matchers. + * + * @author Nhan Huynh + */ +public final class Matchers { + + /** + * Prevent instantiation of this utility class. + */ + private Matchers() { + } + + /** + * Creates a matcher that matches a string with a given string with a minimum similarity + * {@value TestConstants#MINIMUM_SIMILARITY}%. + * + * @param string the string to match + * @param the type of the object to match + * + * @return the matcher + */ + public static Matcher matchString(String string) { + + return new Matcher() { + + @Override + public Match match(ST object) { + return new Match<>() { + + final double similarity = MatchingUtils.similarity(object.string(), string); + + @Override + public boolean matched() { + return similarity >= TestConstants.MINIMUM_SIMILARITY; + } + + @Override + public ST object() { + return object; + } + + @Override + public int compareTo(Match other) { + if (!other.matched()) { + return matched() ? 1 : 0; + } else if (!matched()) { + return -1; + } + double otherSimilarity = MatchingUtils.similarity(other.object().string(), string); + return Double.compare(similarity, otherSimilarity); + } + }; + } + }; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/assertions/Mocks.java b/solution/H08/src/graderPrivate/java/h08/assertions/Mocks.java new file mode 100644 index 0000000..c4468ae --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/assertions/Mocks.java @@ -0,0 +1,70 @@ +package h08.assertions; + +import h08.Flight; +import org.mockito.Mockito; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.time.LocalDateTime; + +/** + * Provides utility methods for creating mock objects. + * + * @author Nhan Huynh + */ +public final class Mocks { + + /** + * Prevents instantiation of this utility class. + */ + private Mocks() { + } + + /** + * Creates a mock flight object with the given parameters. + * + * @param flightNumber the flight number of the flight + * @param departure the departure location of the flight + * @param destination the destination location of the flight + * @param departureTime the departure time of the flight + * @param initialSeats the initial number of seats of the flight + * @param availableSeats the available number of seats of the flight + * + * @return a mock flight object + */ + public static Flight createFlight( + String flightNumber, + String departure, + String destination, + LocalDateTime departureTime, + int initialSeats, + int availableSeats + ) { + Flight flight = Mockito.mock(Flight.class, Mockito.CALLS_REAL_METHODS); + TypeLink typeLink = Links.getType(Flight.class); + FieldLink flightNumberLink = typeLink.getField(Matcher.of(field -> field.name().equals("flightNumber"))); + flightNumberLink.set(flight, flightNumber); + FieldLink departureLink = typeLink.getField(Matcher.of(field -> field.name().equals("departure"))); + departureLink.set(flight, departure); + FieldLink destinationLink = typeLink.getField(Matcher.of(field -> field.name().equals("destination"))); + destinationLink.set(flight, destination); + FieldLink departureTimeLink = typeLink.getField(Matcher.of(field -> field.name().equals("departureTime"))); + departureTimeLink.set(flight, departureTime); + FieldLink initialSeatsLink = typeLink.getField(Matcher.of(field -> field.name().equals("initialSeats"))); + initialSeatsLink.set(flight, initialSeats); + FieldLink availableSeatsLink = typeLink.getField(Matcher.of(field -> field.name().equals("availableSeats"))); + availableSeatsLink.set(flight, availableSeats); + Mockito.when(flight.toString()).thenReturn( + "Flight{" + + "flightNumber='" + flightNumber + '\'' + + ", departure='" + departure + '\'' + + ", destination='" + destination + '\'' + + ", departureTime=" + departureTime + + ", initialSeats=" + initialSeats + + ", availableSeats=" + availableSeats + + '}' + ); + return flight; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/mocks/FakeAirport.java b/solution/H08/src/graderPrivate/java/h08/mocks/FakeAirport.java new file mode 100644 index 0000000..b269d90 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/mocks/FakeAirport.java @@ -0,0 +1,170 @@ +package h08.mocks; + +import h08.Airport; +import h08.Flight; +import h08.TutorUtils; +import h08.assertions.Links; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; +import java.util.Objects; + +/** + * Extension of Airport to make testing easier. + * + * @author Nhan Huynh + */ +public class FakeAirport extends Airport { + + /** + * The field link to the flights departing from this airport. + */ + private final FieldLink departingFlightsLink; + + /** + * The field link to the flights arriving at this airport. + */ + private final FieldLink arrivingFlightsLink; + + /** + * The field link to the number of departing flights. + */ + private final FieldLink departingSizeLink; + + /** + * The field link to the number of arriving flights. + */ + private final FieldLink arrivingSizeLink; + + + /** + * Constructs a new airport with the specified airport code and initial capacity. + * + * @param airportCode the code of the airport + * @param initialCapacity the initial capacity of the airport + */ + public FakeAirport(String airportCode, int initialCapacity) { + this(airportCode, initialCapacity, new Flight[initialCapacity], new Flight[initialCapacity], 0, 0); + } + + /** + * Constructs a new airport with the specified airport code, initial capacity, and flights. + * + * @param airportCode the code of the airport + * @param initialCapacity the initial capacity of the airport + * @param departingFlights the flights departing from this airport + * @param arrivingFlights the flights arriving at this airport + * @param departingSize the number of departing flights + * @param arrivingSize the number of arriving flights + */ + public FakeAirport( + String airportCode, + int initialCapacity, + Flight[] departingFlights, + Flight[] arrivingFlights, + int departingSize, + int arrivingSize + ) { + super(airportCode, initialCapacity); + TypeLink typeLink = Links.getType(Airport.class); + this.departingFlightsLink = typeLink.getField(Matcher.of(field -> field.name().equals("departingFlights"))); + this.arrivingFlightsLink = typeLink.getField(Matcher.of(field -> field.name().equals("arrivingFlights"))); + this.departingSizeLink = typeLink.getField(Matcher.of(field -> field.name().equals("departingSize"))); + this.arrivingSizeLink = typeLink.getField(Matcher.of(field -> field.name().equals("arrivingSize"))); + + copyFlights(this.departingFlightsLink, departingFlights); + copyFlights(this.arrivingFlightsLink, arrivingFlights); + this.departingSizeLink.set(this, departingSize); + this.arrivingSizeLink.set(this, arrivingSize); + } + + /** + * Sets the capacity of flights departing from this airport. + * + * @param link the field link to set the capacity of flights departing from this airport + * @param flights the capacity of flights departing from this airport + */ + private void copyFlights(FieldLink link, Flight[] flights) { + Flight[] actual = link.get(this); + if (flights.length > actual.length) { + actual = new Flight[flights.length]; + } + link.set(this, actual); + System.arraycopy(flights, 0, actual, 0, flights.length); + } + + /** + * Returns the capacity of flights departing from this airport. + * + * @return the capacity of flights departing from this airport + */ + public Flight[] getDepartingFlights() { + return departingFlightsLink.get(this); + } + + /** + * Returns the capacity of flights arriving from this airport. + * + * @return the capacity of flights arriving from this airport + */ + public Flight[] getArrivingFlights() { + return arrivingFlightsLink.get(this); + } + + /** + * Returns the number of departing flights. + * + * @return the number of departing flights + */ + public int getDepartingSize() { + return departingSizeLink.get(this); + } + + /** + * Returns the number of arriving flights. + * + * @return the number of arriving flights + */ + public int getArrivingSize() { + return arrivingSizeLink.get(this); + } + + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (!(object instanceof Airport that)) { + return false; + } + return Objects.equals(getAirportCode(), that.getAirportCode()) + && TutorUtils.equalFlights(getDepartingFlights(), departingFlightsLink.get(that)) + && TutorUtils.equalFlights(getArrivingFlights(), arrivingFlightsLink.get(that)) + && getDepartingSize() == departingSizeLink.get(that) + && getArrivingSize() == arrivingSizeLink.get(that); + } + + /** + * Returns a string representation of the flights. + * + * @param flights the flights to convert to a string + * + * @return a string representation of the flights + */ + private String flightsToString(Flight[] flights) { + return Arrays.stream(flights).map(it -> it == null ? null : it.getFlightNumber()).toList().toString(); + } + + @Override + public String toString() { + return "Airport{" + + "departingFlights=" + flightsToString(getDepartingFlights()) + + ", departingSize=" + getDepartingSize() + + ", arrivingFlights=" + flightsToString(getArrivingFlights()) + + ", arrivingSize=" + getArrivingSize() + + '}'; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/mocks/FakeBookingManagement.java b/solution/H08/src/graderPrivate/java/h08/mocks/FakeBookingManagement.java new file mode 100644 index 0000000..3c7ccf5 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/mocks/FakeBookingManagement.java @@ -0,0 +1,82 @@ +package h08.mocks; + +import h08.Booking; +import h08.BookingManagement; +import h08.FlightManagement; +import h08.assertions.Links; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.ArrayList; +import java.util.List; + +public class FakeBookingManagement extends BookingManagement { + + private final List bookings = new ArrayList<>(); + private final FieldLink bookingsLink; + private final FieldLink sizeLink; + private final FieldLink flightManagementLink; + + /** + * Constructs a new booking management with the specified initial capacity and flight management. + * + * @param initialCapacity the initial number of bookings that can be managed + * @param flightManagement the flight management for the bookings + */ + public FakeBookingManagement(int initialCapacity, FlightManagement flightManagement) { + super(initialCapacity, flightManagement); + TypeLink typeLink = Links.getType(BookingManagement.class); + this.bookingsLink = Links.getField(typeLink, "bookings"); + this.sizeLink = Links.getField(typeLink, "size"); + this.flightManagementLink = Links.getField(typeLink, "flightManagement"); + } + + public FakeBookingManagement(FlightManagement flightManagement, List bookings) { + this(bookings.size(), flightManagement); + setBookings(bookings); + } + + public void update() { + setBookings(getBookings()); + } + + public Booking[] getBookings() { + return bookingsLink.get(this); + } + + public int size() { + return sizeLink.get(this); + } + + private void setSize(int size) { + sizeLink.set(this, size); + } + + public FlightManagement getFlightManagement() { + return flightManagementLink.get(this); + } + + public void setBookings(Booking[] bookings) { + setBookings(List.of(bookings)); + } + + public void setBookings(List bookings) { + this.bookings.clear(); + this.bookings.addAll(bookings); + this.bookingsLink.set(this, this.bookings.toArray(Booking[]::new)); + setSize(bookings.size()); + } + + public void addBooking(Booking booking) { + bookings.add(booking); + update(); + } + + @Override + public String toString() { + return "FakeBookingManagement{" + + "bookings=" + bookings + + ", flightManagement=" + getFlightManagement() + + '}'; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/Builder.java b/solution/H08/src/graderPrivate/java/h08/rubric/Builder.java new file mode 100644 index 0000000..1cad266 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/Builder.java @@ -0,0 +1,18 @@ +package h08.rubric; + +/** + * A builder interface for building objects. + * + * @param the type of object to build + * + * @author Nhan Huynh + */ +public interface Builder { + + /** + * Builds the object. + * + * @return the built object + */ + T build(); +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/Criteriable.java b/solution/H08/src/graderPrivate/java/h08/rubric/Criteriable.java new file mode 100644 index 0000000..d780831 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/Criteriable.java @@ -0,0 +1,19 @@ +package h08.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; + +/** + * An object that implements this interface indicates that it can be converted to a {@link Criterion} which means + * it is gradable. + * + * @author Nhan Huynh + */ +public interface Criteriable { + + /** + * Returns the criterion that represents this object. + * + * @return the criterion that represents this object + */ + Criterion getCriterion(); +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/Rubrics.java b/solution/H08/src/graderPrivate/java/h08/rubric/Rubrics.java new file mode 100644 index 0000000..6700945 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/Rubrics.java @@ -0,0 +1,103 @@ +package h08.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Grader; +import org.sourcegrade.jagr.api.rubric.JUnitTestRef; +import org.tudalgo.algoutils.tutor.general.jagr.RubricUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +/** + * Utility class for creating {@link Criterion} instances. + * + * @author Nhan Huynh + */ +public final class Rubrics { + + /** + * Prevent instantiation of this utility class. + */ + private Rubrics() { + } + + /** + * Returns a pre-configured criterion builder where the description and grader are set. + * + * @param description the description of the criterion + * @param grader the grader of the criterion + * + * @return a pre-configured criterion builder with the description and grader set + */ + public static Criterion.Builder criterionBuilder(String description, Grader grader) { + return Criterion.builder() + .shortDescription(description) + .grader(grader); + } + + /** + * Returns a pre-configured criterion builder where the description and test reference are set. + * + * @param description the description of the criterion + * @param testRef the test reference of the criterion + * + * @return a pre-configured criterion builder with the description and test reference set + */ + public static Criterion.Builder criterionBuilder(String description, JUnitTestRef testRef) { + return criterionBuilder( + description, + Grader.testAwareBuilder() + .requirePass(testRef) + .pointsFailedMin() + .pointsPassedMax() + .build() + ); + } + + /** + * Creates a criterion supplier with the given description, class name, test methods signature, and points. + * Since the points can only be determined after all subtasks are added, the points are calculated lazily. + * + * @param description the description of the criterion + * @param className the name of the test class that tests this subtask + * @param testMethodsSignature the signature of the test methods + * @param points the points of the criterion + * + * @return a criterion supplier with the given description, class name, test methods signature, and points + */ + public static Supplier criterion( + String description, + String className, + Map>> testMethodsSignature, + Supplier points + ) { + return () -> { + Criterion.Builder builder; + try { + List testRefs = new ArrayList<>(testMethodsSignature.size()); + for (Map.Entry>> entry : testMethodsSignature.entrySet()) { + Method method = Class.forName(className).getDeclaredMethod( + entry.getKey(), + entry.getValue().toArray(Class[]::new) + ); + testRefs.add(JUnitTestRef.ofMethod(method)); + } + builder = criterionBuilder(description, JUnitTestRef.and(testRefs.toArray(JUnitTestRef[]::new))); + } catch (Exception e) { + builder = criterionBuilder(description, RubricUtils.graderPrivateOnly()); + } + int pointsValue = points.get(); + if (pointsValue >= 0) { + builder.minPoints(0); + builder.maxPoints(pointsValue); + } else { + builder.maxPoints(0); + builder.minPoints(pointsValue); + } + return builder.build(); + }; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/TaskRubricProvider.java b/solution/H08/src/graderPrivate/java/h08/rubric/TaskRubricProvider.java new file mode 100644 index 0000000..22b285d --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/TaskRubricProvider.java @@ -0,0 +1,62 @@ +package h08.rubric; + +import h08.rubric.task.Task; +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; + +import java.util.List; + +/** + * A TaskRubricProvider is a RubricProvider that provides a Rubric for an assignment and allows for customizations. + * + * @author Nhan Huynh + */ +public abstract class TaskRubricProvider implements RubricProvider { + + /** + * The task number of the assignment. + */ + private final int taskNumber; + + /** + * The title of the assignment. + */ + private final String title; + + /** + * Whether the tests are public or private. + */ + private final boolean privateTests; + + /** + * Creates a new TaskRubricProvider with the given task number, title, and whether the tests are public or private. + * + * @param taskNumber the task number of the assignment + * @param title the title of the assignment + * @param privateTests whether the tests are public or private + */ + public TaskRubricProvider(int taskNumber, String title, boolean privateTests) { + this.taskNumber = taskNumber; + this.title = title; + this.privateTests = privateTests; + } + + /** + * Gets the tasks for the assignment. + * + * @return the tasks for the assignment + */ + public abstract List getTasks(); + + @Override + public Rubric getRubric() { + return Rubric.builder() + .title("H%02d | %s - %s Tests".formatted(taskNumber, title, privateTests ? "Private" : "Public")) + .addChildCriteria( + getTasks().stream() + .map(Task::getCriterion) + .toArray(Criterion[]::new) + ).build(); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/BasicSubtestInformationBuilder.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/BasicSubtestInformationBuilder.java new file mode 100644 index 0000000..2c75bc6 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/BasicSubtestInformationBuilder.java @@ -0,0 +1,36 @@ +package h08.rubric.context; + +import org.tudalgo.algoutils.tutor.general.assertions.Property; +import org.tudalgo.algoutils.tutor.general.assertions.basic.BasicProperty; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +public abstract class BasicSubtestInformationBuilder> + implements SubtestInformation.SubtestInformationBuilder { + + protected final List properties = new ArrayList<>(); + + protected abstract B self(); + + @Override + public B add(String information, Object description) { + ListIterator iterator = properties.listIterator(); + String valueString = String.valueOf(description); + while (iterator.hasNext()) { + Property property = iterator.next(); + if (property.key().equals(information)) { + iterator.set(new BasicProperty(information, valueString)); + return self(); + } + } + properties.add(new BasicProperty(information, valueString)); + return self(); + } + + @Override + public SubtestInformation build() { + return new SubtestInformation(properties); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilder.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilder.java new file mode 100644 index 0000000..17fd8e1 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilder.java @@ -0,0 +1,10 @@ +package h08.rubric.context; + +/** + * A builder for creating input test case related information. + * + * @author Nhan Huynh + */ +public interface InputTestInformationBuilder + extends SubtestInformation.SubtestInformationBuilder { +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilderImpl.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilderImpl.java new file mode 100644 index 0000000..d20e1f1 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/InputTestInformationBuilderImpl.java @@ -0,0 +1,15 @@ +package h08.rubric.context; + +/** + * An implementation of {@link InputTestInformationBuilder}. + * + * @author Nhan Huynh + */ +class InputTestInformationBuilderImpl extends BasicSubtestInformationBuilder + implements InputTestInformationBuilder { + + @Override + protected InputTestInformationBuilder self() { + return this; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilder.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilder.java new file mode 100644 index 0000000..c58e699 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilder.java @@ -0,0 +1,12 @@ +package h08.rubric.context; + +import org.jetbrains.annotations.Nullable; + +/** + * A builder for creating output test case related information. + */ +public interface OutputTestInformationBuilder + extends SubtestInformation.SubtestInformationBuilder { + + OutputTestInformationBuilder cause(@Nullable Class exception); +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilderImpl.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilderImpl.java new file mode 100644 index 0000000..1078fbd --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/OutputTestInformationBuilderImpl.java @@ -0,0 +1,24 @@ +package h08.rubric.context; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.tutor.general.assertions.basic.BasicProperty; + +/** + * An implementation of {@link OutputTestInformationBuilder}. + * + * @author Nhan Huynh + */ +class OutputTestInformationBuilderImpl extends BasicSubtestInformationBuilder + implements OutputTestInformationBuilder { + + @Override + protected OutputTestInformationBuilder self() { + return this; + } + + @Override + public OutputTestInformationBuilder cause(@Nullable Class exception) { + properties.add(new BasicProperty("Throws", exception == null ? "Nothing" : exception.getName())); + return this; + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/SubtestInformation.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/SubtestInformation.java new file mode 100644 index 0000000..4c6c687 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/SubtestInformation.java @@ -0,0 +1,38 @@ +package h08.rubric.context; + +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.assertions.Property; + +import java.util.Collection; + +/** + * Contains sub information about a test case which divides the main information into structured parts. + * + * @param properties the properties of the subtest information + */ +public record SubtestInformation(Collection properties) implements Context { + + @Override + public Object subject() { + return null; + } + + /** + * A builder for {@link SubtestInformation}. + * + * @param the type of the builder + */ + public interface SubtestInformationBuilder> + extends h08.rubric.Builder { + + /** + * Adds information to the test case. + * + * @param information the information to add + * @param description the description of the information + * + * @return this builder instance with the information added + */ + B add(String information, Object description); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/context/TestInformation.java b/solution/H08/src/graderPrivate/java/h08/rubric/context/TestInformation.java new file mode 100644 index 0000000..6fac308 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/context/TestInformation.java @@ -0,0 +1,234 @@ +package h08.rubric.context; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.assertions.Property; + +import java.util.Collection; +import java.util.function.Function; + +/** + * Provides more context information to the test results by adding information about the input, expected output, and + * actual output of the test. + * + * @author Nhan Huynh + */ +public class TestInformation implements Context { + + /** + * The subject of the test case. + */ + private final Object subject; + + /** + * The information about the test case. + */ + private final Collection properties; + + /** + * Constructs new test information with the given test case and information. + * + * @param subject the test case of the test + * @param require the input test case information of the test + * @param ensure the expected output test case information of the test + * @param actual the actual output test case information of the test + */ + public TestInformation( + Object subject, + @Nullable SubtestInformation require, + @Nullable SubtestInformation ensure, + @Nullable SubtestInformation actual) { + Context.Builder builder = Assertions2.contextBuilder() + .subject(subject); + + if (require != null) { + addState(builder, "Input", require); + } + if (ensure != null) { + addState(builder, "Expected output", ensure); + } + if (actual != null) { + addState(builder, "Actual output", actual); + } + Context context = builder.build(); + this.subject = context.subject(); + this.properties = context.properties(); + } + + /** + * Creates a builder for {@link TestInformation}. + * + * @return a builder for {@link TestInformation} + */ + public static TestInformationBuilder builder() { + return new TestInformationBuilderImpl(); + } + + /** + * Adds the given state to the builder with the given name. + * + * @param builder the builder to add the state to + * @param name the name of the state + * @param state the state to add + */ + private void addState(Builder builder, String name, SubtestInformation state) { + if (state != null) { + builder.add( + name, + Assertions2.contextBuilder() + .add(state.properties().toArray(Property[]::new)) + .build() + ); + } + } + + @Override + public Object subject() { + return subject; + } + + @Override + public Collection properties() { + return properties; + } + + /** + * A builder for {@link TestInformation}. + */ + public interface TestInformationBuilder extends h08.rubric.Builder { + + /** + * Sets the test case of the test. + * + * @param subject the test case of the test + * + * @return this builder instance after setting the test case + */ + TestInformationBuilder subject(Object subject); + + /** + * Sets the input information of the test. + * + * @param input the input information of the test + * + * @return this builder instance after setting the input information of the test + */ + TestInformationBuilder input(SubtestInformation input); + + /** + * Sets the input information of the test. + * + * @param builder the builder for creating the input information of the test + * + * @return this builder instance after setting the input information of the test + */ + TestInformationBuilder input(Function builder); + + /** + * Sets the expected output information of the test. + * + * @param expect the expected output information of the test + * + * @return this builder instance after setting the expected output information of the test + */ + TestInformationBuilder expect(SubtestInformation expect); + + /** + * Sets the expected output information of the test. + * + * @param builder the builder for creating the expected output information of the test + * + * @return this builder instance after setting the expected output information of the test + */ + TestInformationBuilder expect(Function builder); + + /** + * Sets the actual output information of the test. + * + * @param actual the actual output information of the test + * + * @return this builder instance after setting the actual output information of the test + */ + TestInformationBuilder actual(SubtestInformation actual); + + /** + * Sets the actual output information of the test. + * + * @param builder the builder for creating the actual output information of the test + * + * @return this builder instance after setting the actual output information of the test + */ + TestInformationBuilder actual(Function builder); + } + + /** + * An implementation of {@link TestInformationBuilder}. + */ + private static class TestInformationBuilderImpl implements TestInformationBuilder { + + /** + * The test case of the test. + */ + private @Nullable Object subject; + + /** + * The input information of the test. + */ + private @Nullable SubtestInformation input; + + /** + * The expected output information of the test. + */ + private @Nullable SubtestInformation expect; + + /** + * The actual output information of the test. + */ + private @Nullable SubtestInformation actual; + + @Override + public TestInformationBuilder subject(Object subject) { + this.subject = subject; + return this; + } + + @Override + public TestInformationBuilder input(SubtestInformation input) { + this.input = input; + return this; + } + + @Override + public TestInformationBuilder input(Function input) { + return input(input.apply(new InputTestInformationBuilderImpl()).build()); + } + + @Override + public TestInformationBuilder expect(SubtestInformation expect) { + this.expect = expect; + return this; + } + + @Override + public TestInformationBuilder expect(Function expect) { + return expect(expect.apply(new OutputTestInformationBuilderImpl()).build()); + } + + @Override + public TestInformationBuilder actual(SubtestInformation actual) { + this.actual = actual; + return this; + } + + @Override + public TestInformationBuilder actual(Function actual) { + return actual(actual.apply(new OutputTestInformationBuilderImpl()).build()); + } + + @Override + public TestInformation build() { + return new TestInformation(subject, input, expect, actual); + } + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTask.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTask.java new file mode 100644 index 0000000..cf165a4 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTask.java @@ -0,0 +1,150 @@ +package h08.rubric.task; + +import h08.rubric.Builder; +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.List; +import java.util.Map; + +/** + * Represents an atomic task in a rubric. + * An atomic task is a task that does not contain child tasks, and the criteria + * are defined at the same level as the task itself. + * + * @author Nhan Huynh + */ +public interface AtomicTask extends Task { + + /** + * Creates a new builder for {@link AtomicTask}. + * + * @return a new builder for {@link AtomicTask} + */ + static AtomicTaskBuilder builder() { + return new AtomicTaskImpl.AtomicTaskBuilderImpl<>(AtomicTaskImpl::new); + } + + /** + * Returns the criteria of this atomic task that must be met to complete the subtask. + * + * @return the criteria of this atomic task that must be met to complete the subtask + */ + List criteria(); + + /** + * Returns the requirements that must be met to complete the subtask. + * + * @return the requirements that must be met to complete the subtask + */ + List requirements(); + + /** + * A builder for {@link AtomicTask}. + * + * @param the type of the {@link AtomicTask} to build + */ + interface AtomicTaskBuilder extends Builder { + + /** + * Sets the description of the atomic task. + * + * @param description the description of the subtask + * + * @return this builder instance with the description set + */ + AtomicTaskBuilder description(String description); + + /** + * Sets the name of the test class that tests this atomic task. + * + * @param testClassName the name of the test class that tests this subtask + * + * @return this builder instance with the test class name set + */ + AtomicTaskBuilder testClassName(String testClassName); + + /** + * Adds a criterion to the atomic task. + * + * @param description the description of the criterion + * @param privateTest whether the test is private or public + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the criterion added + */ + AtomicTaskBuilder criterion( + String description, + boolean privateTest, + Map>> testMethodsSignature + ); + + /** + * Adds a private criterion to the atomic task. + * + * @param description the description of the criterion + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the criterion added + */ + default AtomicTaskBuilder criterion(String description, Map>> testMethodsSignature) { + return criterion(description, true, testMethodsSignature); + } + + /** + * Adds a criterion to the atomic task. + * + * @param description the description of the criterion + * @param privateTest whether the test is private or public + * @param testMethodName the name of the test method + * @param testMethodParameters the signature of the test method + * + * @return this builder instance with the criterion added + */ + default AtomicTaskBuilder criterion( + String description, + boolean privateTest, + String testMethodName, + Class... testMethodParameters + ) { + return criterion(description, privateTest, Map.of(testMethodName, List.of(testMethodParameters))); + } + + /** + * Adds a private criterion to the atomic task. + * + * @param description the description of the criterion + * @param testMethodName the name of the test method + * @param testMethodSignature the signature of the test method + * + * @return this builder instance with the criterion added + */ + default AtomicTaskBuilder criterion(String description, String testMethodName, + Class... testMethodSignature) { + return criterion(description, true, testMethodName, testMethodSignature); + } + + /** + * Adds a requirement to the atomic task. + * + * @param description the description of the requirement + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the requirement added + */ + AtomicTaskBuilder requirement(String description, Map>> testMethodsSignature); + + /** + * Adds a requirement to the atomic task. + * + * @param description the description of the requirement + * @param testMethodName the name of the test method + * @param testMethodParameters the signature of the test method + * + * @return this builder instance with the requirement added + */ + default AtomicTaskBuilder requirement(String description, String testMethodName, + Class... testMethodParameters) { + return requirement(description, Map.of(testMethodName, List.of(testMethodParameters))); + } + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTaskImpl.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTaskImpl.java new file mode 100644 index 0000000..66cdd1b --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/AtomicTaskImpl.java @@ -0,0 +1,182 @@ +package h08.rubric.task; + +import h08.rubric.Rubrics; +import h08.util.TriFunction; +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Gradable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/** + * An implementation of {@link AtomicTask}. + * + * @author Nhan Huynh + */ +class AtomicTaskImpl implements AtomicTask { + + /** + * The description of the atomic task. + */ + private final String description; + + /** + * The criteria of the atomic task that must be met to complete the subtask. + */ + private final List criteria; + + /** + * The requirements that must be met to complete the subtask. + */ + private final List requirements; + + /** + * Creates a new {@link AtomicTaskImpl} with the given description, criteria, and requirements. + * + * @param description the description of the atomic task + * @param criteria the criteria of the atomic task that must be met to complete the subtask + * @param requirements the requirements that must be met to complete the subtask + */ + AtomicTaskImpl(String description, List criteria, List requirements) { + this.description = description; + this.criteria = criteria; + this.requirements = requirements; + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .minPoints(0) + .addChildCriteria(Stream.concat(criteria.stream(), requirements.stream()).toArray(Criterion[]::new)) + .build(); + } + + @Override + public List criteria() { + return criteria; + } + + @Override + public List requirements() { + return requirements; + } + + @Override + public String description() { + return description; + } + + @Override + public boolean equals(Object obj) { + return this == obj + || obj instanceof AtomicTaskImpl that + && Objects.equals(description, that.description) + && Objects.equals(criteria, that.criteria) + && Objects.equals(requirements, that.requirements); + } + + @Override + public int hashCode() { + return Objects.hash(description, criteria, requirements); + } + + static class AtomicTaskBuilderImpl implements AtomicTaskBuilder { + + /** + * The constructor to invoke to create a new {@link AtomicTask}. + */ + private final TriFunction, List, A> constructor; + + /** + * The description of the atomic task. + */ + private @NotNull String description = ""; + + /** + * The name of the test class that tests this atomic task. + */ + private @NotNull String testClassName = ""; + + /** + * The criteria of the atomic task that must be met to complete the subtask. + */ + private final List> criteria = new ArrayList<>(); + + /** + * The requirements that must be met to complete the subtask. + */ + private final List> requirements = new ArrayList<>(); + + /** + * Creates a new {@link AtomicTaskBuilderImpl} with the given constructor to create a new {@link AtomicTask}. + * + * @param constructor the constructor to invoke to create a new {@link AtomicTask} + */ + AtomicTaskBuilderImpl(TriFunction, List, A> constructor) { + this.constructor = Objects.requireNonNull(constructor); + } + + @Override + public AtomicTaskBuilder description(String description) { + this.description = description; + return this; + } + + @Override + public AtomicTaskBuilder testClassName(String testClassName) { + this.testClassName = testClassName; + return this; + } + + @Override + public AtomicTaskBuilder criterion( + String description, + boolean privateTest, + Map>> testMethodsSignature + ) { + criteria.add( + Rubrics.criterion( + description, + testClassName + (privateTest ? "Private" : "Public"), + testMethodsSignature, + () -> 1 + ) + ); + return this; + } + + @Override + public AtomicTaskBuilder requirement(String description, Map>> testMethodsSignature) { + requirements.add( + Rubrics.criterion( + description, + testClassName + "Private", + testMethodsSignature, + () -> -criteria.stream() + .map(Supplier::get) + .mapToInt(Gradable::getMaxPoints) + .sum() + ) + ); + return this; + } + + @Override + public A build() { + if (testClassName.isBlank()) { + throw new IllegalStateException("Test class name must be set!"); + } + return constructor.apply( + description, + criteria.stream().map(Supplier::get).toList(), + requirements.stream().map(Supplier::get).toList() + ); + } + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTask.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTask.java new file mode 100644 index 0000000..a50130a --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTask.java @@ -0,0 +1,64 @@ +package h08.rubric.task; + +import h08.rubric.Builder; + +import java.util.List; + +/** + * Represents a composite task in a rubric. A composite task is a task that contains child tasks. + * + * @author Nhan Huynh + */ +public interface CompositeTask extends Task { + + /** + * Creates a new builder for {@link CompositeTask}. + * + * @return a new builder for {@link CompositeTask} + */ + static CompositeTaskBuilder builder() { + return new CompositeTaskImpl.CompositeTaskBuilderImpl(); + } + + /** + * Returns the subtasks of this composite task. + * + * @return the subtasks of this composite task + */ + List subtasks(); + + /** + * A builder for {@link CompositeTask}. + */ + interface CompositeTaskBuilder extends Builder { + + /** + * Sets the description of the composite task. + * + * @param description the description of the composite task + * + * @return this builder instance with the description set + */ + CompositeTaskBuilder description(String description); + + /** + * Adds subtasks to the composite task. + * + * @param subtasks the subtasks to add + * + * @return this builder instance with the subtasks added + */ + CompositeTaskBuilder subtasks(Subtask... subtasks); + + /** + * Adds a criterion to the composite task. + * + * @param criterion the criterion to add + * + * @return this builder instance with the criterion added + */ + default CompositeTaskBuilder subtask(Subtask criterion) { + return subtasks(criterion); + } + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTaskImpl.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTaskImpl.java new file mode 100644 index 0000000..29d8239 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/CompositeTaskImpl.java @@ -0,0 +1,80 @@ +package h08.rubric.task; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * An implementation of a {@link CompositeTask}. + * + * @param description the description of the composite task + * @param subtasks the subtasks of the composite task that must be completed to complete the task + * + * @author Nhan Huynh + */ +record CompositeTaskImpl(String description, List subtasks) implements CompositeTask { + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .addChildCriteria( + subtasks.stream() + .map(Subtask::getCriterion) + .toArray(Criterion[]::new) + ) + .build(); + } + + @Override + public boolean equals(Object obj) { + return this == obj + || obj instanceof CompositeTaskImpl that + && Objects.equals(description, that.description) + && Objects.equals(subtasks, that.subtasks); + } + + @Override + public int hashCode() { + return Objects.hash(description, subtasks); + } + + /** + * A builder for {@link CompositeTask}. + */ + static class CompositeTaskBuilderImpl implements CompositeTaskBuilder { + + /** + * The description of the composite task. + */ + private @NotNull String description = ""; + + /** + * The subtasks of the composite task that must be completed to complete the task. + */ + private final List criteria = new ArrayList<>(); + + @Override + public CompositeTaskBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public CompositeTaskBuilder subtasks(Subtask... subtasks) { + this.criteria.addAll(List.of(subtasks)); + return this; + } + + @Override + public CompositeTask build() { + if (description.isBlank()) { + throw new IllegalArgumentException("Description must be set!"); + } + return new CompositeTaskImpl(description, criteria); + } + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/Subtask.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/Subtask.java new file mode 100644 index 0000000..a9b86fa --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/Subtask.java @@ -0,0 +1,18 @@ +package h08.rubric.task; + +/** + * Represents a subtask in a rubric. A subtask is an atomic task that is part of a composite task. + * + * @author Nhan Huynh + */ +public interface Subtask extends AtomicTask { + + /** + * Creates a new builder for {@link Subtask}. + * + * @return a new builder for {@link Subtask} + */ + static AtomicTaskBuilder builder() { + return new AtomicTaskImpl.AtomicTaskBuilderImpl<>(SubtaskImpl::new); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/SubtaskImpl.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/SubtaskImpl.java new file mode 100644 index 0000000..cdfde29 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/SubtaskImpl.java @@ -0,0 +1,24 @@ +package h08.rubric.task; + +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.List; + +/** + * An implementation of {@link Subtask}. + * + * @author Nhan Huynh + */ +class SubtaskImpl extends AtomicTaskImpl implements Subtask { + + /** + * Creates a new instance of {@link SubtaskImpl}. + * + * @param description the description of the subtask + * @param criteria the criteria of the subtask that must be met to complete the subtask + * @param requirements the requirements that must be met to complete the subtask + */ + SubtaskImpl(String description, List criteria, List requirements) { + super(description, criteria, requirements); + } +} diff --git a/solution/H08/src/graderPrivate/java/h08/rubric/task/Task.java b/solution/H08/src/graderPrivate/java/h08/rubric/task/Task.java new file mode 100644 index 0000000..6766be7 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/rubric/task/Task.java @@ -0,0 +1,13 @@ +package h08.rubric.task; + +import h08.rubric.Criteriable; + +/** + * Represents a task in a rubric. + * + * @author Nhan Huynh + */ +public interface Task extends Criteriable { + + String description(); +} diff --git a/solution/H08/src/graderPrivate/java/h08/util/TriFunction.java b/solution/H08/src/graderPrivate/java/h08/util/TriFunction.java new file mode 100644 index 0000000..4909d59 --- /dev/null +++ b/solution/H08/src/graderPrivate/java/h08/util/TriFunction.java @@ -0,0 +1,42 @@ +package h08.util; + +import java.util.Objects; +import java.util.function.Function; + +/** + * Represents a function that accepts three arguments and produces a result. + * + * @param the type of the first argument to the function + * @param the type of the second argument to the function + * @param the type of the third argument to the function + * @param the type of the result of the function + * + * @author Nhan Huynh + */ +public interface TriFunction { + + /** + * Applies this function to the given arguments. + * + * @param a the first function argument + * @param b the second function argument + * @param c the third function argument + * + * @return the result of the function + */ + R apply(A a, B b, C c); + + /** + * Returns a composed function that first applies this function to its input. + * + * @param after and then applies the {@code after} function to the result. + * @param the type of output of the {@code after} function + * + * @return a composed function that first applies this function and then applies the {@code after} function + */ + default TriFunction andThen( + Function after) { + Objects.requireNonNull(after); + return (A a, B b, C c) -> after.apply(apply(a, b, c)); + } +} diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_1_generatePassengerID.json b/solution/H08/src/graderPrivate/resources/h08/H08_1_generatePassengerID.json new file mode 100644 index 0000000..1ad5781 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_1_generatePassengerID.json @@ -0,0 +1,18 @@ +[ + { + "firstName": "Felix", + "lastName": "Lee", + "dateOfBirth": "2000-09-15", + "passengerID": "FL4096591", + "expectedInitials": "FL", + "expectedHash": "4096591" + }, + { + "firstName": "Kim", + "lastName": "Min-Jeong", + "dateOfBirth": "2001-01-01", + "passengerID": "KM0101011", + "expectedInitials": "KM", + "expectedHash": "4098113" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_2_1_testFlightConstructor.json b/solution/H08/src/graderPrivate/resources/h08/H08_2_1_testFlightConstructor.json new file mode 100644 index 0000000..cbd8ce6 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_2_1_testFlightConstructor.json @@ -0,0 +1,30 @@ +[ + { + "flightNumber": "LH1234", + "departure": null, + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100 + }, + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": null, + "departureTime": "2025-02-07 13:00", + "initialSeats": 100 + }, + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": null, + "initialSeats": 100 + }, + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": -1 + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_2_1_testValidateFlightNumberException.json b/solution/H08/src/graderPrivate/resources/h08/H08_2_1_testValidateFlightNumberException.json new file mode 100644 index 0000000..83a70d7 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_2_1_testValidateFlightNumberException.json @@ -0,0 +1,23 @@ +[ + { + "flightNumber": "LH12" + }, + { + "flightNumber": "L123" + }, + { + "flightNumber": "L1234" + }, + { + "flightNumber": "1234" + }, + { + "flightNumber": "123456" + }, + { + "flightNumber": "LHASDF" + }, + { + "flightNumber": "L9" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_2_2_testBookSeat.json b/solution/H08/src/graderPrivate/resources/h08/H08_2_2_testBookSeat.json new file mode 100644 index 0000000..c81bdd8 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_2_2_testBookSeat.json @@ -0,0 +1,56 @@ +[ + { + "preFlight": { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 100 + }, + "postFlight": { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 99 + } + }, + { + "preFlight": { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 67 + }, + "postFlight": { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 66 + } + }, + { + "preFlight": { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "postFlight": { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlight.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlight.json new file mode 100644 index 0000000..acae520 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlight.json @@ -0,0 +1,248 @@ +[ + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + } + ], + "arrivingFlights": [], + "departingSize": 2, + "arrivingSize": 0 + }, + "flight": { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + }, + "isDeparting": true + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + } + ], + "arrivingFlights": [], + "departingSize": 2, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + }, + { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 17:00", + "initialSeats": 100, + "availableSeats": 5 + }, + null + ], + "arrivingFlights": [], + "departingSize": 3, + "arrivingSize": 0 + }, + "flight": { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 17:00", + "initialSeats": 100, + "availableSeats": 5 + }, + "isDeparting": true + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 0, + "arrivingSize": 1 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + } + ], + "departingSize": 0, + "arrivingSize": 2 + }, + "flight": { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + }, + "isDeparting": false + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + } + ], + "departingSize": 0, + "arrivingSize": 2 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 5 + }, + { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 17:00", + "initialSeats": 100, + "availableSeats": 5 + }, + null + ], + "departingSize": 0, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 17:00", + "initialSeats": 100, + "availableSeats": 5 + }, + "isDeparting": false + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlightException.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlightException.json new file mode 100644 index 0000000..78c0b54 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_1_testAddFlightException.json @@ -0,0 +1,92 @@ +[ + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "flight": { + "flightNumber": "VN300", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isDeparting": true + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "flight": { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isDeparting": false + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlight.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlight.json new file mode 100644 index 0000000..1357ba8 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlight.json @@ -0,0 +1,476 @@ +[ + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + } + ], + "arrivingFlights": [], + "departingSize": 4, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [ + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + }, + null + ], + "arrivingFlights": [], + "departingSize": 3, + "arrivingSize": 0 + }, + "flightNumber": "LH1234", + "isDeparting": true + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + } + ], + "arrivingFlights": [], + "departingSize": 4, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1237", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + }, + null + ], + "arrivingFlights": [], + "departingSize": 3, + "arrivingSize": 0 + }, + "flightNumber": "LH1236", + "isDeparting": true + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + } + ], + "arrivingFlights": [], + "departingSize": 4, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [ + { + "flightNumber": "LH1234", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "FRA", + "destination": "ICN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + null + ], + "arrivingFlights": [], + "departingSize": 3, + "arrivingSize": 0 + }, + "flightNumber": "LH1237", + "isDeparting": true + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + } + ], + "departingSize": 0, + "arrivingSize": 4 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + }, + null + ], + "departingSize": 0, + "arrivingSize": 3 + }, + "flightNumber": "LH1234", + "isDeparting": false + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + } + ], + "departingSize": 0, + "arrivingSize": 4 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1237", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + }, + null + ], + "departingSize": 0, + "arrivingSize": 3 + }, + "flightNumber": "LH1236", + "isDeparting": false + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + { + "flightNumber": "LH1237", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 16:00", + "initialSeats": 100, + "availableSeats": 7 + } + ], + "departingSize": 0, + "arrivingSize": 4 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 4, + "departingFlights": [], + "arrivingFlights": [ + { + "flightNumber": "LH1234", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH1235", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH1236", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 20 + }, + null + ], + "departingSize": 0, + "arrivingSize": 3 + }, + "flightNumber": "LH1237", + "isDeparting": false + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlightException.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlightException.json new file mode 100644 index 0000000..f05510e --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_2_testRemoveFlightException.json @@ -0,0 +1,80 @@ +[ + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "flightNumber": "VN302", + "isDeparting": true, + "message": "Departing flight not found: VN302" + }, + { + "preAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "postAirport": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [], + "departingSize": 1, + "arrivingSize": 0 + }, + "flightNumber": "VN303", + "isDeparting": false, + "message": "Arriving flight not found: VN303" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlight.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlight.json new file mode 100644 index 0000000..199639f --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlight.json @@ -0,0 +1,416 @@ +[ + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isDeparting": true + }, + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + "isDeparting": true + }, + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + }, + "isDeparting": true + }, + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isDeparting": false + }, + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + "isDeparting": false + }, + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + }, + "isDeparting": false + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlightException.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlightException.json new file mode 100644 index 0000000..a76f0f8 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_3_testGetFlightException.json @@ -0,0 +1,142 @@ +[ + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "VN700", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 17:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isDeparting": true, + "message": "Departing flight not found: VN700" + }, + { + "airport": { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + "flight": { + "flightNumber": "VN700", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 17:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isDeparting": false, + "message": "Arriving flight not found: VN700" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBooking.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBooking.json new file mode 100644 index 0000000..37408ab --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBooking.json @@ -0,0 +1,11 @@ +[ + { + "booking": { + "bookingId": "iKON", + "flightNumber": "2019", + "passengerId": "B.I", + "isCancelled": false + }, + "isCancelled": false + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBookingException.json b/solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBookingException.json new file mode 100644 index 0000000..cb74e0e --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_4_4_testCancelBookingException.json @@ -0,0 +1,12 @@ +[ + { + "booking": { + "bookingId": "HYBE-20241129", + "flightNumber": "NewJeans", + "passengerId": "Hanni", + "isCancelled": true + }, + "isCancelled": true, + "message": "Booking is already cancelled: HYBE-20241129" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlight.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlight.json new file mode 100644 index 0000000..04cad2f --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlight.json @@ -0,0 +1,392 @@ +[ + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + { + "airportCode": "IATA ", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "IH300", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IN400", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IN500", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "IH300", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IH400", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IH500", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + } + ] + }, + "flight": { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + { + "airportCode": "IATA ", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "IH300", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IN400", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IN500", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "IH300", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IH400", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IH500", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + } + ] + }, + "flight": { + "flightNumber": "IH400", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + } + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + { + "airportCode": "IATA ", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "IH300", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IN400", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IN500", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "IH300", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IH400", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IH500", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + } + ] + }, + "flight": { + "flightNumber": "IN500", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlightNull.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlightNull.json new file mode 100644 index 0000000..9fc9e58 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testGetFlightNull.json @@ -0,0 +1,133 @@ +[ + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN400", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "VN500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "LH300", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "LH400", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "LH500", + "departure": "ICN", + "destination": "FRA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + }, + { + "airportCode": "IATA ", + "initialCapacity": 3, + "departingFlights": [ + { + "flightNumber": "IH300", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IN400", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IN500", + "departure": "IATA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "arrivingFlights": [ + { + "flightNumber": "IH300", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "IH400", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 14:00", + "initialSeats": 100, + "availableSeats": 12 + }, + { + "flightNumber": "IH500", + "departure": "ICN", + "destination": "IATA", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + } + ], + "departingSize": 3, + "arrivingSize": 3 + } + ] + }, + "flight": { + "flightNumber": "IL500", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 15:00", + "initialSeats": 100, + "availableSeats": 2 + }, + "message": "Error retrieving flight: Flight not found: IL500" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirport.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirport.json new file mode 100644 index 0000000..1154646 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirport.json @@ -0,0 +1,177 @@ +[ + { + "flightManagement": { + "airports": [ + { + "airportCode": "LAX-022AB", + "departingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "initialCapacity": 1, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "SFO-045DC", + "departingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 08:30", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 10:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 09:00", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "initialCapacity": 2, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + } + ] + }, + "airportCode": "JFK-017XY", + "airport": { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirportException.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirportException.json new file mode 100644 index 0000000..c8ab7c5 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchAirportException.json @@ -0,0 +1,136 @@ +[ + { + "flightManagement": { + "airports": [ + { + "airportCode": "LAX-022AB", + "departingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "initialCapacity": 1, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "SFO-045DC", + "departingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 08:30", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 10:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 09:00", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "initialCapacity": 2, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + } + ] + }, + "airportCode": "JFK-0174K", + "message": "Airport not found: JFK-0174K" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchFlight.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchFlight.json new file mode 100644 index 0000000..15d7ddc --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_1_testSearchFlight.json @@ -0,0 +1,547 @@ +[ + { + "flightManagement": { + "airports": [ + { + "airportCode": "LAX-022AB", + "departingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "initialCapacity": 1, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "SFO-045DC", + "departingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 08:30", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 10:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 09:00", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "initialCapacity": 2, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + } + ] + }, + "airportCode": "JFK-017XY", + "airport": { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + }, + "flightNumber": "VAN-6234", + "flight": { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "LAX-022AB", + "departingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "initialCapacity": 1, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "SFO-045DC", + "departingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 08:30", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 10:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 09:00", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "initialCapacity": 2, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + } + ] + }, + "airportCode": "JFK-017XY", + "airport": { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + }, + "flightNumber": "VAN-7234", + "flight": null + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "LAX-022AB", + "departingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "LAX-022AB", + "destination": "SFO", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-4213", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 08:00", + "initialSeats": 100, + "availableSeats": 50 + }, + { + "flightNumber": "VAN-4214", + "departure": "SFO", + "destination": "LAX-022AB", + "departureTime": "2020-12-01 09:00", + "initialSeats": 100, + "availableSeats": 50 + } + ], + "initialCapacity": 1, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "SFO-045DC", + "departingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 08:30", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 10:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 09:00", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "initialCapacity": 2, + "departingSize": 2, + "arrivingSize": 2 + }, + { + "airportCode": "JFK-017XY", + "departingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 07:00", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "JFK-017XY", + "destination": "LAX", + "departureTime": "2020-12-01 09:00", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-6233", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 08:30", + "initialSeats": 150, + "availableSeats": 100 + }, + { + "flightNumber": "VAN-6234", + "departure": "LAX", + "destination": "JFK-017XY", + "departureTime": "2020-12-01 10:30", + "initialSeats": 150, + "availableSeats": 100 + } + ], + "initialCapacity": 3, + "departingSize": 2, + "arrivingSize": 2 + } + ] + }, + "airportCode": "SFO-045DC", + "airport": { + "airportCode": "SFO-045DC", + "departingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 08:30", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5224", + "departure": "SFO-045DC", + "destination": "LAX", + "departureTime": "2020-12-01 10:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VAN-5223", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 09:00", + "initialSeats": 120, + "availableSeats": 80 + }, + { + "flightNumber": "VAN-5221", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + ], + "initialCapacity": 2, + "departingSize": 2, + "arrivingSize": 2 + }, + "flightNumber": "VAN-5221", + "flight": { + "flightNumber": "VAN-5221", + "departure": "LAX", + "destination": "SFO-045DC", + "departureTime": "2020-12-01 11:00", + "initialSeats": 120, + "availableSeats": 80 + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_2_testManageFlight.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_2_testManageFlight.json new file mode 100644 index 0000000..a2f577a --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_2_testManageFlight.json @@ -0,0 +1,274 @@ +[ + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "airportCode": "FRA", + "flight": { + "flightNumber": "VN609", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-08 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isAddOperation": true, + "expected": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + }, + { + "flightNumber": "VN609", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-08 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 2, + "arrivingSize": 1 + } + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "airportCode": "FRA", + "flight": { + "flightNumber": "VN609", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-08 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isAddOperation": true, + "expected": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + { + "flightNumber": "VN609", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-08 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 2 + } + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "airportCode": "FRA", + "flight": { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + }, + "isAddOperation": false, + "expected": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 0, + "arrivingSize": 1 + } + }, + { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "airportCode": "FRA", + "flight": { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + }, + "isAddOperation": false, + "expected": { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + ], + "departingSize": 1, + "arrivingSize": 0 + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingDuplicate.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingDuplicate.json new file mode 100644 index 0000000..a1babc5 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingDuplicate.json @@ -0,0 +1,56 @@ +[ + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingInvalid.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingInvalid.json new file mode 100644 index 0000000..ff74361 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_2_validateAndCheckBookingInvalid.json @@ -0,0 +1,326 @@ +[ + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": null, + "flightNumber": "VN600", + "passengerId": "NL123456" + }, + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "", + "flightNumber": "VN600", + "passengerId": "NL123456" + }, + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "DSA123", + "flightNumber": null, + "passengerId": "NL123456" + }, + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "DSA123", + "flightNumber": "", + "passengerId": "NL123456" + }, + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "DSA123", + "flightNumber": "VN600", + "passengerId": null + }, + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "DSA123", + "flightNumber": "VN600", + "passengerId": "" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBooking.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBooking.json new file mode 100644 index 0000000..d8cda31 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBooking.json @@ -0,0 +1,80 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + } + }, + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + } + }, + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBookingException.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBookingException.json new file mode 100644 index 0000000..f27818d --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testGetBookingException.json @@ -0,0 +1,30 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "KX273", + "flightNumber": "KK200", + "passengerId": "PK123456" + }, + "message": "Error retrieving booking: Booking not found: KX273" + } +] + diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBooking.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBooking.json new file mode 100644 index 0000000..d8cda31 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBooking.json @@ -0,0 +1,80 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + } + }, + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + } + }, + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBookingException.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBookingException.json new file mode 100644 index 0000000..9a33504 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_3_testSearchBookingException.json @@ -0,0 +1,30 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "KX273", + "flightNumber": "KK200", + "passengerId": "PK123456" + }, + "message": "Booking not found: KX273" + } +] + diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBooking.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBooking.json new file mode 100644 index 0000000..da3964c --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBooking.json @@ -0,0 +1,83 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + "message": "Booking cancelled successfully: B001" + }, + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + "message": "Booking cancelled successfully: B002" + }, + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + }, + "message": "Booking cancelled successfully: B003" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingAlreadyCancelled.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingAlreadyCancelled.json new file mode 100644 index 0000000..837a6a1 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingAlreadyCancelled.json @@ -0,0 +1,32 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456", + "isCancelled": true + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456", + "isCancelled": true + }, + "message": "Already cancelled booking: B001" + } +] + diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingNotFound.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingNotFound.json new file mode 100644 index 0000000..bf0d463 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_4_testCancelBookingNotFound.json @@ -0,0 +1,30 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "booking": { + "bookingId": "B324", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + "message": "Error cancelling booking: Booking not found: B324" + } +] + diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBooking.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBooking.json new file mode 100644 index 0000000..62339e2 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBooking.json @@ -0,0 +1,61 @@ +[ + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "B004", + "flightNumber": "VN600", + "passengerId": "FL999999", + "booking": { + "bookingId": "B004", + "flightNumber": "VN600", + "passengerId": "FL999999" + } + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingDuplicate.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingDuplicate.json new file mode 100644 index 0000000..a485fd0 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingDuplicate.json @@ -0,0 +1,57 @@ +[ + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456", + "message": "Booking already exists: B001" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingInvalid.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingInvalid.json new file mode 100644 index 0000000..8a0f0cf --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingInvalid.json @@ -0,0 +1,57 @@ +[ + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "", + "flightNumber": "VN600", + "passengerId": "KL123456", + "message": "Invalid booking details: Invalid booking details provided." + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingNoSeats.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingNoSeats.json new file mode 100644 index 0000000..ec8e27e --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingNoSeats.json @@ -0,0 +1,57 @@ +[ + { + "bookingManagement": { + "flightManagement": { + "airports": [ + { + "airportCode": "FRA", + "initialCapacity": 2, + "departingFlights": [ + { + "flightNumber": "VN300", + "departure": "FRA", + "destination": "SGN", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 0 + } + ], + "arrivingFlights": [ + { + "flightNumber": "VN600", + "departure": "SGN", + "destination": "FRA", + "departureTime": "2025-02-07 13:00", + "initialSeats": 100, + "availableSeats": 1 + } + ], + "departingSize": 1, + "arrivingSize": 1 + } + ] + }, + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "VN600", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "VN300", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "VN600", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "KS123456", + "flightNumber": "VN300", + "passengerId": "BJ123456", + "message": "" + } +] diff --git a/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingValidation.json b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingValidation.json new file mode 100644 index 0000000..2d23812 --- /dev/null +++ b/solution/H08/src/graderPrivate/resources/h08/H08_5_5_testCreateBookingValidation.json @@ -0,0 +1,26 @@ +[ + { + "bookingManagement": { + "bookings": [ + { + "bookingId": "B001", + "flightNumber": "TG100", + "passengerId": "FL123456" + }, + { + "bookingId": "B002", + "flightNumber": "LH402", + "passengerId": "NN700212" + }, + { + "bookingId": "B003", + "flightNumber": "KK200", + "passengerId": "NO020304" + } + ] + }, + "bookingId": "B004", + "flightNumber": "TG100", + "passengerId": "FL999999" + } +] diff --git a/solution/H08/src/main b/solution/H08/src/main new file mode 120000 index 0000000..96a2e25 --- /dev/null +++ b/solution/H08/src/main @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H08/src/main \ No newline at end of file diff --git a/solution/H08/src/test b/solution/H08/src/test new file mode 120000 index 0000000..e9bb0fe --- /dev/null +++ b/solution/H08/src/test @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H08/src/test \ No newline at end of file diff --git a/solution/H08/version b/solution/H08/version new file mode 100644 index 0000000..b694fe3 --- /dev/null +++ b/solution/H08/version @@ -0,0 +1 @@ +0.1.0-SNAPSHOT diff --git a/solution/H09/.editorconfig b/solution/H09/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/solution/H09/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/solution/H09/.gitignore b/solution/H09/.gitignore new file mode 100644 index 0000000..1ce268f --- /dev/null +++ b/solution/H09/.gitignore @@ -0,0 +1,86 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +screenshots/ diff --git a/solution/H09/README.md b/solution/H09/README.md new file mode 100644 index 0000000..12432ad --- /dev/null +++ b/solution/H09/README.md @@ -0,0 +1,4 @@ +# Musterlösung zu Hausübung 09 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/solution/H07/build.gradle.kts b/solution/H09/build.gradle.kts similarity index 85% rename from solution/H07/build.gradle.kts rename to solution/H09/build.gradle.kts index 0b67281..910fc13 100644 --- a/solution/H07/build.gradle.kts +++ b/solution/H09/build.gradle.kts @@ -6,7 +6,7 @@ plugins { version = file("version").readLines().first() exercise { - assignmentId.set("h07") + assignmentId.set("h09") } submission { @@ -30,8 +30,8 @@ jagr { val graderPublic by getting val graderPrivate by creating { parent(graderPublic) - graderName.set("FOP-2425-H07-Private") - rubricProviderName.set("h07.H07_RubricProvider") + graderName.set("FOP-2425-H09-Private") + rubricProviderName.set("h09.H09_RubricProvider") } } } diff --git a/solution/H09/gradle/libs.versions.toml b/solution/H09/gradle/libs.versions.toml new file mode 100644 index 0000000..2a961b5 --- /dev/null +++ b/solution/H09/gradle/libs.versions.toml @@ -0,0 +1,3 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } +style = { id = "org.sourcegrade.style", version = "3.0.0" } diff --git a/solution/H09/gradle/wrapper/gradle-wrapper.jar b/solution/H09/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/solution/H09/gradlew.bat b/solution/H09/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/solution/H09/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/solution/H07/settings.gradle.kts b/solution/H09/settings.gradle.kts similarity index 90% rename from solution/H07/settings.gradle.kts rename to solution/H09/settings.gradle.kts index b01e157..1493de4 100644 --- a/solution/H07/settings.gradle.kts +++ b/solution/H09/settings.gradle.kts @@ -8,4 +8,4 @@ dependencyResolutionManagement { } } -rootProject.name = "H07-Root" +rootProject.name = "H09-Root" diff --git a/solution/H09/src/graderPrivate/java/h09/H09_RubricProvider.java b/solution/H09/src/graderPrivate/java/h09/H09_RubricProvider.java new file mode 100644 index 0000000..c150a86 --- /dev/null +++ b/solution/H09/src/graderPrivate/java/h09/H09_RubricProvider.java @@ -0,0 +1,73 @@ +package h09; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; + +import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.criterion; + +public class H09_RubricProvider implements RubricProvider { + + public static final Rubric RUBRIC = Rubric.builder() + .title("H09") + .addChildCriteria( + Criterion.builder() + .shortDescription("H9.1 | StackOfObjects") + .addChildCriteria( + criterion("Der generische Typparameter O wird korrekt deklariert und das Attribut " + + "objs wird korrekt initialisiert."), + criterion("push wird korrekt mit generischem Typparameter angepasst."), + criterion("remove wird korrekt mit generischem Typparameter angepasst."), + criterion("get und pop werden korrekt mit generischem Typparameter angepasst."), + criterion("of wird korrekt mit generischem Typparameter angepasst.", 2) + ) + .build(), + Criterion.builder() + .shortDescription("H9.2 | Generische Typen beschränken") + .addChildCriteria( + criterion("Der generische Typparameter von Enclosure wird korrekt deklariert und beschränkt."), + criterion("Enclosure::getStack von Enclosure wird korrekt mit generischem Typparameter angepasst."), + criterion("Waterenclosure besitzt einen korrekt beschränkten Typparameter und implementiert Enclosure korrekt."), + criterion("Waterenclosure::getStack funktioniert korrekt."), + criterion("Waterenclosure::feed getStack funktioniert korrekt.", 2), + criterion("Waterenclosure::getMeanElevation getStack funktioniert korrekt.") + ) + .build(), + Criterion.builder() + .shortDescription("H9.3 | Bearbeitung von Enclosures mit funktionalen Interfaces") + .addChildCriteria( + criterion("forEach hat korrekt beschränkte Typparameter.", 3), + criterion("filterObj hat korrekt beschränkte Typparameter.", 3), + criterion("filterFunc hat korrekt beschränkte Typparameter.", 4), + criterion("filterFunc gibt korrekt ein neues Enclosure mit gefilterten Tieren zurück.", 2) + ) + .build(), + Criterion.builder() + .shortDescription("H9.4 | Predicates and Consumer mit Lambda") + .addChildCriteria( + criterion("SWIMS_AT_LOW_ELEVATION funktioniert korrekt und wurde korrekt beschränkt."), + criterion("FEED_AND_SLEEP funktioniert korrekt und wurde korrekt beschränkt."), + criterion("EAT_AND_SINK() gibt einen korrekten Consumer zurück, welcher korrekt beschränkt ist.", 2) + ) + .build(), + Criterion.builder() + .shortDescription("H9.5 | Enclosure::forEach") + .addChildCriteria( + criterion("Drei Lion Objekte werden erstellt sowie gefüttert und einfache Fehlfunktionen der Methode forEach werden erkannt."), + criterion("Zwei Penguin Objekte werden korrekt erstellt, bewegt und gefüttert."), + criterion("Einfache Fehlfunktionen der Methode filterFunc werden erkannt.") + ) + .build() + ) + .build(); + + @Override + public Rubric getRubric() { + return RUBRIC; + } + +// @Override +// public void configure(final RubricConfiguration configuration) { +// configuration.addTransformer(new AccessTransformer()); +// } +} diff --git a/solution/H09/src/graderPrivate/java/h09/TemplateAnnotationProcessor.java b/solution/H09/src/graderPrivate/java/h09/TemplateAnnotationProcessor.java new file mode 100644 index 0000000..e38361e --- /dev/null +++ b/solution/H09/src/graderPrivate/java/h09/TemplateAnnotationProcessor.java @@ -0,0 +1,154 @@ +package h09; + +import org.junit.jupiter.api.Test; +import org.tudalgo.algoutils.student.annotation.SolutionOnly; +import org.tudalgo.algoutils.student.annotation.StudentCreationRequired; +import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; +import spoon.Launcher; +import spoon.reflect.CtModel; +import spoon.reflect.code.CtCodeSnippetStatement; +import spoon.reflect.declaration.CtAnnotation; +import spoon.reflect.declaration.CtElement; +import spoon.reflect.declaration.CtMethod; +import spoon.reflect.declaration.CtRecord; +import spoon.reflect.factory.Factory; +import spoon.support.sniper.SniperJavaPrettyPrinter; + +import java.io.File; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +import static org.tudalgo.algoutils.tutor.general.ResourceUtils.toPathString; + +public class TemplateAnnotationProcessor { + private static Launcher createSpoonLauncher(final boolean sniper) { + final Launcher spoon = new Launcher(); + spoon.getEnvironment().setAutoImports(true); + spoon.getEnvironment().setComplianceLevel(17); + spoon.getEnvironment().setNoClasspath(true); + spoon.getEnvironment().setCommentEnabled(true); + spoon.getEnvironment().setIgnoreSyntaxErrors(true); + if (sniper) { + spoon.getEnvironment().setPrettyPrinterCreator( + () -> new SniperJavaPrettyPrinter(spoon.getEnvironment()) + ); + } + return spoon; + } + + @Test + public void execute() { + // final Collection types = List.of(BasicTypeLink.of(TestClass.class)); + final Collection types = BasicPackageLink.of("h09").getTypes(); + Path tmpDir = null; + try { + tmpDir = Files.createTempDirectory("spoon_output"); + System.out.println("tmpdir: " + tmpDir.toString()); + for (final BasicTypeLink type : types) { + if (type.reflection().getName().contains("TemplateAnnotationProcessor") || type.reflection().getName().contains("TestClass")) { + continue; + } + System.out.println("processing " + type.name()); + final AtomicBoolean modified = new AtomicBoolean(false); + Launcher spoon = createSpoonLauncher(true); + spoon.addInputResource(getFilePath(type).toString()); + CtModel model = spoon.buildModel(); + var spoonClass = model.getAllTypes().stream().filter(it -> it.getQualifiedName().equals(type.reflection().getName())).findFirst().orElse(null); + if (spoonClass == null || spoonClass instanceof CtRecord) { + // workaround for records because spoon hates them + spoon = createSpoonLauncher(false); + spoon.addInputResource(getFilePath(type).toString()); + model = spoon.buildModel(); + spoonClass = model.getAllTypes().stream().filter(it -> it.getQualifiedName().equals(type.reflection().getName())).findFirst().orElseThrow(); + } + final Factory factory = spoon.getFactory(); + processAnnotation(spoonClass, StudentImplementationRequired.class, element -> { + // get annotation text + final var exercise = element.getAnnotation(StudentImplementationRequired.class).value(); + if (element instanceof final CtMethod method) { + modified.set(true); + // Create a new code snippet statement with the desired code + String optionalReturn = ""; + if (!method.getType().getSimpleName().equals("void")) { + optionalReturn = "return "; + } + final CtCodeSnippetStatement snippet = method.getFactory().Code().createCodeSnippetStatement("// TODO: " + exercise + "\n" + optionalReturn + "org.tudalgo.algoutils.student.Student.crash(\"" + exercise + " - Remove if implemented\")"); + // Set the code snippet as the body of the method + method.setBody(snippet); + } + }); + processAnnotation(spoonClass, Set.of(SolutionOnly.class, StudentCreationRequired.class), element -> { + if (element instanceof final CtMethod method) { + modified.set(true); + // remove annotations + method.getAnnotations().forEach(CtAnnotation::delete); + // remove method + method.delete(); + } + }); + if (!modified.get()) { + continue; + } + // Save the modified class + spoon.getEnvironment().setSourceOutputDirectory(new File(tmpDir.toString())); + // overwrite the file if it already exists +// spoon.getEnvironment().setAutoImports(true); + + spoon.prettyprint(); + final var path = getFilePath(type); + final var outputPath = Path.of(tmpDir.toString(), toPathString(type.reflection().getName())); + Files.deleteIfExists(path); + Files.move(outputPath, path); + } + } catch (final IOException e) { + throw new RuntimeException(e); + } finally { + try (final var walk = Files.walk(tmpDir)) { + walk.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); + } catch (final IOException e) { + throw new RuntimeException("Could not delete tmp dir", e); + } + } + } + + public static Path getFilePath(final TypeLink type) { + final String pathString = toPathString(type.reflection().getName()); + // find the file + try (final var walk = Files.walk(Path.of("."))) { + return walk.filter(p -> p.endsWith(pathString)).findFirst().orElseThrow(); + } catch (final IOException e) { + throw new RuntimeException("an error occurred while reading a source files ", e); + } + } + + public static void processAnnotation( + final CtElement root, final Set> annotations, + final Consumer consumer + ) { + CtElement element = root.filterChildren(c -> annotations.stream().anyMatch(c::hasAnnotation)).first(); + final Set processed = new HashSet<>(); + while (element != null && !processed.contains(element)) { + consumer.accept(element); + processed.add(element); + element = root.filterChildren(c -> !processed.contains(c) && annotations.stream().anyMatch(c::hasAnnotation)).first(); + } + } + + public static void processAnnotation( + final CtElement root, final Class annotation, + final Consumer consumer + ) { + processAnnotation(root, Set.of(annotation), consumer); + } +} diff --git a/solution/H09/src/main b/solution/H09/src/main new file mode 120000 index 0000000..21e66ea --- /dev/null +++ b/solution/H09/src/main @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H09/src/main \ No newline at end of file diff --git a/solution/H09/src/test b/solution/H09/src/test new file mode 120000 index 0000000..e62cbc6 --- /dev/null +++ b/solution/H09/src/test @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H09/src/test \ No newline at end of file diff --git a/solution/H09/version b/solution/H09/version new file mode 100644 index 0000000..b694fe3 --- /dev/null +++ b/solution/H09/version @@ -0,0 +1 @@ +0.1.0-SNAPSHOT diff --git a/solution/H10/.editorconfig b/solution/H10/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/solution/H10/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/solution/H10/.gitignore b/solution/H10/.gitignore new file mode 100644 index 0000000..e3750f8 --- /dev/null +++ b/solution/H10/.gitignore @@ -0,0 +1,86 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +jagr.conf diff --git a/solution/H10/README.md b/solution/H10/README.md new file mode 100644 index 0000000..f579341 --- /dev/null +++ b/solution/H10/README.md @@ -0,0 +1,4 @@ +# Musterlösung zu Hausübung 10 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/solution/H10/build.gradle.kts b/solution/H10/build.gradle.kts new file mode 100644 index 0000000..cb2e39e --- /dev/null +++ b/solution/H10/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + alias(libs.plugins.algomate) + alias(libs.plugins.style) +} + +version = file("version").readLines().first() + +exercise { + assignmentId.set("h10") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "ab12cdef" + firstName = "sol_first" + lastName = "sol_last" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h10.H10_RubricProviderPublic") + } + val graderPrivate by creating { + parent(graderPublic) + graderName.set("FOP-2425-H10-Private") + rubricProviderName.set("h10.H10_RubricProviderPrivate") + } + } +} diff --git a/solution/H10/gradle/libs.versions.toml b/solution/H10/gradle/libs.versions.toml new file mode 100644 index 0000000..2a961b5 --- /dev/null +++ b/solution/H10/gradle/libs.versions.toml @@ -0,0 +1,3 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } +style = { id = "org.sourcegrade.style", version = "3.0.0" } diff --git a/solution/H10/gradle/wrapper/gradle-wrapper.jar b/solution/H10/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c1962a79e29d3e0ab67b14947c167a862655af9b GIT binary patch literal 62076 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 literal 0 HcmV?d00001 diff --git a/solution/H10/gradle/wrapper/gradle-wrapper.properties b/solution/H10/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..36074ad --- /dev/null +++ b/solution/H10/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/solution/H10/gradlew b/solution/H10/gradlew new file mode 100755 index 0000000..aeb74cb --- /dev/null +++ b/solution/H10/gradlew @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/solution/H10/gradlew.bat b/solution/H10/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/solution/H10/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/solution/H10/settings.gradle.kts b/solution/H10/settings.gradle.kts new file mode 100644 index 0000000..b20d11f --- /dev/null +++ b/solution/H10/settings.gradle.kts @@ -0,0 +1,10 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + } +} + +rootProject.name = "H10-Root" diff --git a/solution/H10/src/graderPrivate/java/h10/H10_1_1_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_1_1_TestsPrivate.java new file mode 100644 index 0000000..e398fad --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_1_1_TestsPrivate.java @@ -0,0 +1,24 @@ +package h10; + +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; + +/** + * Defines the private tests for H10.1.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.1 | Liste von Spielern erstellen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_1_TestsPrivate extends H10_1_1_TestsPublic { + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_1_2_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_1_2_TestsPrivate.java new file mode 100644 index 0000000..2b907ae --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_1_2_TestsPrivate.java @@ -0,0 +1,67 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions4; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for H10.1.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.2 | Vorkommen der Karte SKIP zählen - iterativ") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_2_TestsPrivate extends H10_1_CountSkipCards_Tests { + + public static final Map> CONVERTERS = Map.of( + "deck", node -> JsonConverters.toItems(node, JsonConverters::toPlayingCard), + "skips", JsonNode::asInt + ); + + @Override + protected String getImplementationType() { + return "Iterative"; + } + + @Override + public List> getMethodParameters() { + return List.of(ListItem.class); + } + + @DisplayName("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.") + @Override + @ParameterizedTest + @JsonParameterSetTest(value = "H10_1_CountSkipCards.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) throws Throwable { + assertResult(parameters); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion") + @Test + void testLoops() { + Assertions4.assertIsNotRecursively( + ((BasicMethodLink) getMethod()).getCtElement(), + contextBuilder().build(), + result -> "Method should not be recursive." + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_1_3_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_1_3_TestsPrivate.java new file mode 100644 index 0000000..3e02a23 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_1_3_TestsPrivate.java @@ -0,0 +1,67 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions4; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for H10.1.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.3 | Vorkommen der Karte SKIP zählen - rekursiv") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_3_TestsPrivate extends H10_1_CountSkipCards_Tests { + + public static final Map> CONVERTERS = Map.of( + "deck", node -> JsonConverters.toItems(node, JsonConverters::toPlayingCard), + "skips", JsonNode::asInt + ); + + @Override + protected String getImplementationType() { + return "Recursive"; + } + + @Override + public List> getMethodParameters() { + return List.of(ListItem.class); + } + + @DisplayName("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.") + @Override + @ParameterizedTest + @JsonParameterSetTest(value = "H10_1_CountSkipCards.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) throws Throwable { + assertResult(parameters); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Schleifen") + @Test + void testRecursions() { + Assertions4.assertIsNotIteratively( + ((BasicMethodLink) getMethod()).getCtElement(), + contextBuilder().build(), + result -> "Method should not be iterative." + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_1_4_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_1_4_TestsPrivate.java new file mode 100644 index 0000000..3252ae9 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_1_4_TestsPrivate.java @@ -0,0 +1,40 @@ +package h10; + +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions4; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; +import spoon.reflect.code.CtInvocation; +import spoon.reflect.declaration.CtMethod; + +/** + * Defines the private tests for H10.1.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.4 | Vorkommen der Karte SKIP zählen - mit Iterator") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_4_TestsPrivate extends H10_1_4_TestsPublic { + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion") + @Test + void testLoops() { + BasicMethodLink method = (BasicMethodLink) getMethod(); + Assertions4.assertIsNotRecursively( + method.getCtElement(), + contextBuilder().build(), + result -> "Method should not be recursive." + ); + TutorAssertionsPrivate.assertIteratorUsed(method); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_2_1_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_2_1_TestsPrivate.java new file mode 100644 index 0000000..d888e2d --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_2_1_TestsPrivate.java @@ -0,0 +1,36 @@ +package h10; + +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions4; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; + +/** + * Defines the private tests for H10.2.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.1 | Ist dieses Element bereits in der Liste?") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_1_TestsPrivate extends H10_2_1_TestsPublic { + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Schleifen") + @Test + void testRecursions() { + Assertions4.assertIsNotIteratively( + ((BasicMethodLink) getMethod()).getCtElement(), + contextBuilder().build(), + result -> "Method should not be iterative." + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_2_2_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_2_2_TestsPrivate.java new file mode 100644 index 0000000..1f67137 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_2_2_TestsPrivate.java @@ -0,0 +1,86 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions4; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; + +/** + * Defines the private tests for H10.2.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.2 | Auf ein Element in der Liste zugreifen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_2_TestsPrivate extends H10_2_2_TestsPublic { + + @DisplayName("Die Suche wird in der Liste von vorne oder hinten gestartet, je nachdem, welcher Weg kürzer ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_2_Path.json", customConverters = CUSTOM_CONVERTERS) + void testPath(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + boolean searchFromStart = parameters.get("searchFromStart"); + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Index", index) + .add("Search from", searchFromStart ? "start" : "end") + .build(); + + ListItems.itemStream(list.head).forEach(item -> { + if (searchFromStart) { + item.prev = null; + } else { + item.next = null; + } + }); + + Assertions2.call(() -> list.get(index), context, result -> "Search strategy mismatch"); + } + + @DisplayName("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_2_Exception.json", customConverters = CUSTOM_CONVERTERS) + void testException(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + Context context = contextBuilder() + .add("List", list.toString()) + .add("Index", index) + .build(); + + Assertions2.assertThrows( + IndexOutOfBoundsException.class, + () -> list.get(index), + context, + result -> "Expected an IndexOutOfBoundsException to be thrown" + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion") + @Test + void testLoops() { + Assertions4.assertIsNotRecursively( + ((BasicMethodLink) getMethod()).getCtElement(), + contextBuilder().build(), + result -> "Method should not be recursive." + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_2_3_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_2_3_TestsPrivate.java new file mode 100644 index 0000000..e46a988 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_2_3_TestsPrivate.java @@ -0,0 +1,144 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; + +/** + * Defines the private tests for H10.2.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.3 | Ein Element hinzufügen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_3_TestsPrivate extends H10_2_3_TestsPublic { + + @DisplayName("Fall 2: Neues Element an das Ende der Liste wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_End.json", customConverters = CUSTOM_CONVERTERS) + void testEnd(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int element = parameters.get("key"); + List expected = parameters.get("expected"); + int index = list.size(); + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .add("Expected list after adding", expected.toString()) + .build(); + + list.add(index, element); + + // Check elements + TutorAssertions.assertEquals(expected, list.head, context); + + + // Check references + Assertions2.assertNull(list.tail.next, context, result -> "Successor of tail should be null."); + Assertions2.assertSame(items.getLast(), list.tail.prev, context, result -> "oldTail != newTail.prev"); + Assertions2.assertSame(items.getLast().next, list.tail, context, result -> "oldTail.next != newTail"); + + // Old reference to the old tail check + // If the list is size < 2, the old tail predecessor should be null (head.prev = null) + if (list.size > 2) { + Assertions2.assertSame(items.getLast().prev.next, items.getLast(), context, + result -> "oldTail.prev.next != oldTail"); + } + } + + @DisplayName("Fall 4: Neues Element in der Mitte der Liste wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Middle.json", customConverters = CUSTOM_CONVERTERS) + void testMiddle(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + List> itemsBefore = ListItems.itemStream(list.head).toList(); + int index = parameters.get("index"); + int element = parameters.get("key"); + List expected = parameters.get("expected"); + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .add("Expected list after adding", expected.toString()) + .build(); + + list.add(index, element); + List> itemsAfter = ListItems.itemStream(list.head).toList(); + + TutorAssertions.assertEquals(expected, list.head, context); + + // Check references + ListItem added = itemsAfter.get(index); + ListItem addedPrev = itemsBefore.get(index - 1); + ListItem addedNext = itemsBefore.get(index); + Assertions2.assertEquals(added.key, element, context, result -> "Added element mismatch"); + + Assertions2.assertSame(addedPrev.next, added, context, result -> "predecessor.next != added"); + Assertions2.assertSame(addedPrev, added.prev, context, result -> "predecessor != added.prev"); + Assertions2.assertSame(addedNext.prev, added, context, result -> "successor.prev != added"); + Assertions2.assertSame(addedNext, added.next, context, result -> "successor != added.next"); + } + + @DisplayName("Die Größe der Liste wird um 1 erhöht.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Size.json", customConverters = CUSTOM_CONVERTERS) + void testSize(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + int element = parameters.get("key"); + int size = parameters.get("size"); + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .add("Expected size after adding", size) + .build(); + + list.add(index, element); + Assertions2.assertEquals(size, list.size(), context, result -> "Size mismatch"); + } + + @DisplayName("Falls der übergebene key null ist, wird eine IllegalArgumentException geworfen.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Null.json", customConverters = CUSTOM_CONVERTERS) + void testIllegalArgumentException(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + + Context context = Assertions2.contextBuilder() + .add("List", list) + .add("Index to add", index) + .add("Element to add", "null") + .build(); + + Assertions2.assertThrows( + IllegalArgumentException.class, + () -> list.add(index, null), + context, + result -> "Illegal argument exception should be thrown" + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_2_4_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_2_4_TestsPrivate.java new file mode 100644 index 0000000..c0b756e --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_2_4_TestsPrivate.java @@ -0,0 +1,104 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; + +/** + * Defines the private tests for H10.2.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.4 | Ein Element entfernen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_4_TestsPrivate extends H10_2_4_TestsPublic { + + @DisplayName("Der Fall 2 wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_Case2.json", customConverters = CUSTOM_CONVERTERS) + void testCase2(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + ListItem head = items.getFirst(); + ListItem newHead = head.next; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", head) + .build(); + + int removed = getMethod().invoke(list, head); + + // Check the return value + Assertions2.assertEquals(head.key, removed, context, + result -> "Returned value should be the key of the removed item"); + + // Check references + Assertions2.assertSame(newHead, list.head, context, result -> "New head mismatch."); + Assertions2.assertNull(newHead.prev, context, result -> "New head should not have a predecessor."); + } + + @DisplayName("Der Fall 3 wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_Case3.json", customConverters = CUSTOM_CONVERTERS) + void testCase3(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + ListItem newTail = items.get(items.size() - 2); + ListItem toRemove = items.getLast(); + int key = toRemove.key; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", toRemove) + .build(); + + int removed = getMethod().invoke(list, toRemove); + + // Check the return value + Assertions2.assertEquals(key, removed, context, + result -> "Returned value should be the key of the removed item"); + + // Check references + Assertions2.assertSame(newTail, list.tail, context, result -> "New tail should be the last element."); + Assertions2.assertNull(newTail.next, context, result -> "New tail should not have a successor."); + } + + @DisplayName("Die Größe der Liste wird um 1 verringert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_Size.json", customConverters = CUSTOM_CONVERTERS) + void testSize(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int key = parameters.get("key"); + ListItem toRemove = items.stream().filter(item -> item.key.equals(key)).findFirst().orElseThrow(); + int size = parameters.get("size"); + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", toRemove) + .add("Expected size after removal", size) + .build(); + + getMethod().invoke(list, toRemove); + + Assertions2.assertEquals(size, list.size(), context, result -> "Size mismatch"); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_2_5_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_2_5_TestsPrivate.java new file mode 100644 index 0000000..ddd23cb --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_2_5_TestsPrivate.java @@ -0,0 +1,25 @@ +package h10; + +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; + +/** + * Defines the private tests for H10.2.5. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.5 | Alle Elemente entfernen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_5_TestsPrivate extends H10_2_4_TestsPublic { + + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_3_1_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_3_1_TestsPrivate.java new file mode 100644 index 0000000..472df91 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_3_1_TestsPrivate.java @@ -0,0 +1,24 @@ +package h10; + +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; + +/** + * Defines the private tests for H10.3.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.1 | Das nächste Element zurückgeben") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_1_TestsPrivate extends H10_3_1_TestsPublic { + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_3_2_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_3_2_TestsPrivate.java new file mode 100644 index 0000000..6de4de7 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_3_2_TestsPrivate.java @@ -0,0 +1,167 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; + +/** + * Defines the private tests for H10.3.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.2 | Das vorherige Element zurückgeben") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_2_TestsPrivate extends H10_Tests { + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "cyclicIterator"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + @DisplayName("Die Methode hasPrevious() gibt korrekt an, ob es ein vorheriges Element gibt.") + @Test + void testHasPrevious() { + List> testCases = List.of( + List.of(1, 2, 3), + List.of(1), + List.of() + ); + testCases.forEach(elements -> { + DoublyLinkedList list = DoublyLinkedLists.create(elements); + BidirectionalIterator it = list.cyclicIterator(); + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", elements.isEmpty() ? "No elements left" : elements.getFirst()) + .add("Previous element", elements.isEmpty() ? "No elements left" : elements.getLast()) + .build(); + + if (elements.isEmpty()) { + Assertions2.assertFalse(it.hasPrevious(), context, + result -> "hasPrevious() should return false if there are no elements left."); + } else { + Assertions2.assertTrue(it.hasPrevious(), context, + result -> "hasPrevious() should return true if there are elements left."); + } + }); + } + + @DisplayName("Die Methode previous() gibt das vorherige Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testPreviousEmpty() { + List elements = List.of(1, 2, 3); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + List> refs = ListItems.itemStream(items).toList(); + + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", "null") + .add("Previous element", elements.getLast()) + .build(); + + Assertions2.assertEquals(elements.getLast(), it.previous(), context, + result -> "previous() should return the last element of the list."); + Assertions2.assertEquals(refs.getLast(), it.p, context, + result -> "p should point to the last element of the list."); + } + + @DisplayName("Die Methode previous() gibt das vorherige Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testPreviousEnd() { + List elements = List.of(1, 2, 3); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + List> refs = ListItems.itemStream(items).toList(); + + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + it.p = refs.getFirst(); + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", elements.getFirst()) + .add("Previous element", elements.getLast()) + .build(); + + Assertions2.assertEquals(elements.getLast(), it.previous(), context, + result -> "previous() should return the last element of the list."); + Assertions2.assertEquals(refs.getLast(), it.p, context, + result -> "p should point to the last element of the list."); + } + + @DisplayName("Die Methode previous() gibt das vorherige Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextMiddle() { + List elements = List.of(1, 2, 3, 4, 5); + ListItem items = ListItems.toItems(elements); + List> refs = ListItems.itemStream(items).toList(); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + int start = 1; + int end = elements.size() - 1; + for (int i = start; i < end; i++) { + it.p = refs.get(i); + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", elements.get(i)) + .add("Previous element", elements.get(i - 1)) + .build(); + + Assertions2.assertEquals(elements.get(i - 1), it.previous(), context, + result -> "previous() result mismatch"); + Assertions2.assertEquals(refs.get(i - 1), it.p, context, result -> "p reference mismatch"); + } + } + + @DisplayName("Die Methode previous() setzt das Attribut calledRemove auf false.") + @Test + void testCalledRemove() { + List elements = List.of(1, 2, 3, 4, 5); + ListItem items = ListItems.toItems(elements); + + DoublyLinkedList list = DoublyLinkedLists.create(elements); + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + assert items != null; + it.p = items.next; + it.calledRemove = true; + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", elements.get(1)) + .add("Previous element", elements.getFirst()) + .add("calledRemove", true) + .build(); + it.previous(); + + Assertions.assertFalse(it.calledRemove, "calledRemove should be set to false after call"); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_3_3_TestsPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_3_3_TestsPrivate.java new file mode 100644 index 0000000..9ae90be --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_3_3_TestsPrivate.java @@ -0,0 +1,220 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.Links; +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.3.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.3 | Verlierer des Spiels bestimmen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_3_TestsPrivate extends H10_3_3_TestsPublic { + + public static final Map> CONVERTERS = Map.of( + "deck", JsonConverters::toDeck, + "players", node -> JsonConverters.toList(node, JsonConverters::toPlayer), + "loser", JsonNode::intValue + ); + + @DisplayName("Wurde im letzten Zug eine DRAW_TWO-Karte gespielt, so muss der nächste Spieler zwei Karten ziehen, sofern er nicht auch eine DRAW_TWO-Karte spielt.") + @Test + void testDrawTwoLastTurnNoDrawTwo() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.DRAW_TWO); + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + + CardGame game = CardGames.create(players, deck); + + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerTwo) + .add("Playing card", PlayingCard.DRAW_TWO) + .build(); + + int numberOfCards = playerTwo.getHandSize(); + + // Current player turn + getMethod().invoke(game); + + // Next player turn + getMethod().invoke(game); + + // Since he plays one card, he should draw two cards = 1 new card + Assertions2.assertEquals(numberOfCards + 1, playerTwo.getHandSize(), + context, result -> "The next player should draw two cards."); + } + + @DisplayName("Wurde im letzten Zug eine DRAW_TWO-Karte gespielt, so muss der nächste Spieler zwei Karten ziehen, sofern er nicht auch eine DRAW_TWO-Karte spielt.") + @Test + void testDrawTwoLastTurnDrawTwo() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.DRAW_TWO); + playerTwo.takeCard(PlayingCard.DRAW_TWO); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + + CardGame game = CardGames.create(players, deck); + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerTwo) + .add("Player to draw cards", playerThree) + .add("Playing card (first player)", PlayingCard.DRAW_TWO) + .add("Playing card (second player)", PlayingCard.DRAW_TWO) + .build(); + + int numberOfCardsNext = playerTwo.getHandSize(); + int numberOfCardsThird = playerThree.getHandSize(); + + // Current player turn + getMethod().invoke(game); + + // Next player turn + getMethod().invoke(game); + + // Third player turn + getMethod().invoke(game); + + Assertions2.assertEquals(numberOfCardsNext - 1, playerTwo.getHandSize(), context, + result -> "The next player should not draw any cards."); + // Since he plays one card, he should draw four cards = 3 new card + Assertions2.assertEquals(numberOfCardsThird + 3, playerThree.getHandSize(), context, + result -> "The next player should draw two cards."); + } + + @DisplayName("Wurden in den vorherigen Zügen mehrere DRAW_TWO-Karten gespielt, so erhöht sich die Anzahl der zu ziehenden Karten entsprechend.") + @Test + void testDrawTwoMultiple() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.DRAW_TWO); + playerOne.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.DRAW_TWO); + + playerThree.takeCard(PlayingCard.DRAW_TWO); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + + CardGame game = CardGames.create(players, deck); + + int size = playerTwo.getHandSize(); + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerTwo) + .add("Playing cards", List.of(PlayingCard.DRAW_TWO, PlayingCard.DRAW_TWO, PlayingCard.DRAW_TWO)) + .build(); + + // Current player turn + getMethod().invoke(game); + Assertions2.assertEquals(2, game.takeCards, context, + result -> "The number of cards to draw should be 2."); + + // Next player turn + getMethod().invoke(game); + Assertions2.assertEquals(4, game.takeCards, context, + result -> "The number of cards to draw should be 4."); + + // Third player turn + getMethod().invoke(game); + Assertions2.assertEquals(6, game.takeCards, context, + result -> "The number of cards to draw should be 6."); + } + + @DisplayName("Der Spieler, der als letztes Karten in der Hand hat, wird korrekt bestimmt und zurückgegeben.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_3_3_Loser.json", customConverters = CUSTOM_CONVERTERS) + void testLoser(JsonParameterSet parameters) throws Throwable { + List deck = parameters.get("deck"); + List players = parameters.get("players"); + int loser = parameters.get("loser"); + CardGame game = CardGames.create(players, deck); + + MethodLink methodLink = Links.getMethod(getClassType(), "determineLoser"); + Context.Builder builder = Assertions2.contextBuilder() + .subject(methodLink.reflection()) + .add("Deck", deck); + players.forEach(p -> builder.add(p.getName(), p.hand)); + Context context = builder.add("Loser", players.get(loser)).build(); + CardGamePlayer actualLoser = game.determineLoser(); + + Assertions2.assertSame( + players.get(loser), + actualLoser, + context, + result -> "Loser mismatch." + ); + } + + @DisplayName("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen") + @Test + void testDataStructure() { + TutorAssertionsPrivate.assertNoDataStructure(getMethod()); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/H10_RubricProviderPrivate.java b/solution/H10/src/graderPrivate/java/h10/H10_RubricProviderPrivate.java new file mode 100644 index 0000000..17ca866 --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/H10_RubricProviderPrivate.java @@ -0,0 +1,18 @@ +package h10; + +import h10.rubric.H10_RubricProvider; + +/** + * A private rubric provider for H10. + * + * @author Nhan Huynh + */ +public class H10_RubricProviderPrivate extends H10_RubricProvider { + + /** + * Constructs a new public rubric provider. + */ + public H10_RubricProviderPrivate() { + super(false); + } +} diff --git a/solution/H10/src/graderPrivate/java/h10/TutorAssertionsPrivate.java b/solution/H10/src/graderPrivate/java/h10/TutorAssertionsPrivate.java new file mode 100644 index 0000000..b9014ee --- /dev/null +++ b/solution/H10/src/graderPrivate/java/h10/TutorAssertionsPrivate.java @@ -0,0 +1,162 @@ +package h10; + +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; +import spoon.SpoonException; +import spoon.reflect.code.CtInvocation; +import spoon.reflect.declaration.CtElement; +import spoon.reflect.declaration.CtMethod; +import spoon.reflect.reference.CtExecutableReference; +import spoon.reflect.visitor.ImportScanner; +import spoon.reflect.visitor.ImportScannerImpl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Utility class for assertions in the private tests of the tutor. + * + * @author Nhan Huynh + */ +public final class TutorAssertionsPrivate { + + /** + * Blacklist of classes that are not allowed in the solution. + */ + private static final Set> BLACKLIST_CLASSES = Set.of( + Stream.class, + ArrayList.class, + LinkedList.class, + Map.class, + HashMap.class, + Set.class + ); + + /** + * Blacklist of calls that are not allowed in the solution. + */ + private static final Set BLACKLIST_CALLS = Set.of( + "stream" + ); + + /** + * Set of method calls that are required for the solution with iterators. + */ + private static final Set ITERATOR_METHOD_CALLS; + + static { + TypeLink iteratorType = BasicTypeLink.of(Iterator.class); + MethodLink next = iteratorType.getMethod(Matcher.of(m -> m.name().equals("next"))); + MethodLink hasNext = iteratorType.getMethod(Matcher.of(m -> m.name().equals("hasNext"))); + TypeLink listType = BasicTypeLink.of(List.class); + MethodLink iterator = listType.getMethod(Matcher.of(m -> m.name().equals("iterator"))); + ITERATOR_METHOD_CALLS = Set.of(next, hasNext, iterator); + } + + /** + * Prevent instantiation of this utility class. + */ + private TutorAssertionsPrivate() { + + } + + /** + * Asserts that the given method link does not use any data structures. + * + * @param methodLink the method link to check + */ + public static void assertNoDataStructure(MethodLink methodLink) { + CtElement element = ((BasicMethodLink) methodLink).getCtElement(); + ImportScanner scanner = new ImportScannerImpl(); + scanner.computeImports(element); + List> classes = scanner.getAllImports() + .stream() + .map(CtElement::getReferencedTypes) + .flatMap(Collection::stream) + .map(ct -> { + try { + return ct.getActualClass(); + } catch (SpoonException e) { + return null; + } + }) + .filter(Objects::nonNull) + .toList(); + + Context context = Assertions2.contextBuilder() + .subject(methodLink.reflection()) + .add("Imported classes", classes) + .build(); + Assertions2.assertFalse(classes.stream().anyMatch(BLACKLIST_CLASSES::contains), context, + result -> "Data structures are not allowed in this task."); + + List calls = element.filterChildren(e -> e instanceof CtInvocation).map(Object::toString).list(); + Assertions2.assertFalse(calls.stream().anyMatch(BLACKLIST_CALLS::contains), context, + result -> "Data structures are not allowed in this task."); + } + + /** + * Lists all method calls in the given method. + * + * @param method the method to check + * @param visited the set of visited methods so far + * + * @return the set of method calls + */ + private static Set getMethodCalls( + MethodLink method, + Set visited + ) { + CtMethod ctMethod; + try { + ctMethod = ((BasicMethodLink) method).getCtElement(); + } catch (NullPointerException | ArrayIndexOutOfBoundsException e) { + // java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 + // java.lang.NullPointerException: Cannot invoke "String.toCharArray()" because "this.content" is null + // Occurs if we read src code from stdlib - skip them + return Set.of(); + } + return ctMethod.filterChildren(it -> it instanceof CtInvocation) + .list() + .stream() + .filter(element -> element instanceof CtInvocation invocation) + .map(element -> (CtInvocation) element) + .map(CtInvocation::getExecutable) + .map(CtExecutableReference::getActualMethod) + .filter(Objects::nonNull) + .map(BasicMethodLink::of) + .filter(methodLink -> !visited.contains(methodLink)) + .collect(Collectors.toSet()); + } + + /** + * Asserts that the given method link uses an iterator. + * + * @param methodLink the method link to check + */ + public static void assertIteratorUsed(MethodLink methodLink) { + Set methods = getMethodCalls(methodLink, new HashSet<>()); + Context context = Assertions2.contextBuilder() + .subject(methodLink.reflection()) + .add("Method calls", methods) + .build(); + + Assertions2.assertTrue(methods.containsAll(ITERATOR_METHOD_CALLS), context, + result -> "Iterator should be used in this task."); + } +} diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_2_Exception.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_2_Exception.json new file mode 100644 index 0000000..6943366 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_2_Exception.json @@ -0,0 +1,120 @@ +[ + { + "input": [ + 1 + ], + "index": 1 + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5 + ], + "index": -1 + }, + { + "input": [ + 10, + 20, + 30, + 40, + 50, + 60 + ], + "index": 6 + }, + { + "input": [ + 5, + 15, + 25, + 35 + ], + "index": -5 + }, + { + "input": [ + 7, + 14, + 21, + 28, + 35, + 42 + ], + "index": 10 + }, + { + "input": [ + 100, + 200, + 300, + 400, + 500 + ], + "index": -3 + }, + { + "input": [ + 9, + 18, + 27, + 36, + 45 + ], + "index": 5 + }, + { + "input": [ + 3, + 6, + 9, + 12, + 15, + 18, + 21 + ], + "index": -10 + }, + { + "input": [ + 8, + 16, + 24, + 32, + 40, + 48, + 56, + 64 + ], + "index": 12 + }, + { + "input": [ + 11, + 22, + 33, + 44, + 55, + 66 + ], + "index": -8 + }, + { + "input": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20 + ], + "index": 20 + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_2_Path.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_2_Path.json new file mode 100644 index 0000000..f34fbf9 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_2_Path.json @@ -0,0 +1,162 @@ +[ + { + "input": [ + 1, + 2, + 3, + 4, + 5 + ], + "index": 1, + "searchFromStart": true + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5 + ], + "index": 2, + "searchFromStart": false + }, + { + "input": [ + 1, + 2, + 3, + 4 + ], + "index": 2, + "searchFromStart": false + }, + { + "input": [ + 10, + 20, + 30, + 40, + 50, + 60 + ], + "index": 5, + "searchFromStart": false + }, + { + "input": [ + 7, + 14, + 21, + 28, + 35, + 42 + ], + "index": 2, + "searchFromStart": true + }, + { + "input": [ + 100, + 200, + 300, + 400, + 500, + 600, + 700 + ], + "index": 6, + "searchFromStart": false + }, + { + "input": [ + 5, + 15, + 25, + 35, + 45, + 55, + 65, + 75 + ], + "index": 3, + "searchFromStart": true + }, + { + "input": [ + 3, + 6, + 9, + 12, + 15, + 18, + 21, + 24, + 27 + ], + "index": 8, + "searchFromStart": false + }, + { + "input": [ + 8, + 16, + 24, + 32, + 40, + 48, + 56, + 64, + 72, + 80 + ], + "index": 4, + "searchFromStart": true + }, + { + "input": [ + 11, + 22, + 33, + 44, + 55, + 66 + ], + "index": 2, + "searchFromStart": true + }, + { + "input": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20 + ], + "index": 7, + "searchFromStart": false + }, + { + "input": [ + 9, + 18, + 27, + 36, + 45, + 54, + 63, + 72, + 81, + 90, + 99, + 108 + ], + "index": 3, + "searchFromStart": true + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_3_End.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_End.json new file mode 100644 index 0000000..b1f8c86 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_End.json @@ -0,0 +1,50 @@ +[ + { + "input": [ + 25 + ], + "key": 55, + "expected": [ + 25, + 55 + ] + }, + { + "input": [ + 25, + 69 + ], + "key": 55, + "expected": [ + 25, + 69, + 55 + ] + }, + { + "input": [ + 25, + 69, + 12, + 9, + 10, + 23, + 45, + 55, + 26 + ], + "key": 55, + "expected": [ + 25, + 69, + 12, + 9, + 10, + 23, + 45, + 55, + 26, + 55 + ] + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Middle.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Middle.json new file mode 100644 index 0000000..bdcbc14 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Middle.json @@ -0,0 +1,61 @@ +[ + { + "input": [ + 1, + 2, + 3 + ], + "key": 5, + "index": 1, + "expected": [ + 1, + 5, + 2, + 3 + ] + }, + { + "input": [ + 1, + 2, + 3 + ], + "key": 5, + "index": 2, + "expected": [ + 1, + 2, + 5, + 3 + ] + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "key": 5, + "index": 5, + "expected": [ + 1, + 2, + 3, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 10 + ] + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Null.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Null.json new file mode 100644 index 0000000..0a64b5b --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Null.json @@ -0,0 +1,42 @@ +[ + { + "input": [ + ], + "index": 0 + }, + { + "input": [ + 1 + ], + "index": 1 + }, + { + "input": [ + 3, + 1 + ], + "index": 0 + }, + { + "input": [ + 3, + 1 + ], + "index": 1 + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "index": 5 + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Size.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Size.json new file mode 100644 index 0000000..03959f5 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_3_Size.json @@ -0,0 +1,38 @@ +[ + { + "input": [ + 1, + 2, + 3 + ], + "key": 4, + "index": 0, + "size": 4 + }, + { + "input": [ + 1, + 2, + 3 + ], + "key": 4, + "index": 3, + "size": 4 + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "key": 4, + "index": 5, + "size": 10 + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case2.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case2.json new file mode 100644 index 0000000..df790f5 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case2.json @@ -0,0 +1,26 @@ +[ + { + "input": [ + 4, + 5 + ] + }, + { + "input": [ + 4, + 5, + 1 + ] + }, + { + "input": [ + 4, + 5, + 2321, + 123, + 0, + 32, + 1 + ] + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case3.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case3.json new file mode 100644 index 0000000..df790f5 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Case3.json @@ -0,0 +1,26 @@ +[ + { + "input": [ + 4, + 5 + ] + }, + { + "input": [ + 4, + 5, + 1 + ] + }, + { + "input": [ + 4, + 5, + 2321, + 123, + 0, + 32, + 1 + ] + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Size.json b/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Size.json new file mode 100644 index 0000000..43cf148 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_2_4_Size.json @@ -0,0 +1,40 @@ +[ + { + "input": [ + 1 + ], + "key": 1, + "size": 0 + }, + { + "input": [ + 1, + 5 + ], + "key": 1, + "size": 1 + }, + { + "input": [ + 5, + 1 + ], + "key": 1, + "size": 1 + }, + { + "input": [ + 5, + 2, + 7, + 10, + 12, + 42, + 0, + 22, + 113 + ], + "key": 10, + "size": 8 + } +] diff --git a/solution/H10/src/graderPrivate/resources/h10/H10_3_3_Loser.json b/solution/H10/src/graderPrivate/resources/h10/H10_3_3_Loser.json new file mode 100644 index 0000000..e8fbf30 --- /dev/null +++ b/solution/H10/src/graderPrivate/resources/h10/H10_3_3_Loser.json @@ -0,0 +1,256 @@ +[ + { + "deck": [ + "DRAW_TWO", + "SKIP", + "SKIP", + "DRAW_TWO", + "DRAW_TWO", + "DRAW_TWO", + "REVERSE", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "PASS", + "SKIP", + "PASS", + "SKIP", + "REVERSE", + "PASS", + "PASS", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "SKIP", + "PASS", + "SKIP", + "REVERSE", + "DRAW_TWO", + "REVERSE", + "PASS", + "PASS", + "PASS", + "SKIP", + "REVERSE", + "DRAW_TWO", + "PASS", + "SKIP", + "REVERSE", + "REVERSE", + "DRAW_TWO", + "DRAW_TWO", + "PASS", + "DRAW_TWO", + "DRAW_TWO", + "SKIP", + "SKIP", + "REVERSE", + "PASS", + "DRAW_TWO", + "DRAW_TWO", + "SKIP", + "REVERSE", + "DRAW_TWO", + "DRAW_TWO", + "REVERSE", + "REVERSE", + "DRAW_TWO", + "PASS", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "SKIP", + "REVERSE", + "SKIP", + "REVERSE", + "DRAW_TWO", + "PASS", + "SKIP", + "SKIP", + "DRAW_TWO", + "REVERSE", + "DRAW_TWO", + "SKIP", + "SKIP", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "SKIP" + ], + "players": [ + { + "name": "G-Dragon", + "hand": [ + "PASS", + "PASS", + "PASS", + "DRAW_TWO", + "SKIP" + ] + }, + { + "name": "Daesung", + "hand": [ + "REVERSE", + "PASS", + "PASS", + "REVERSE", + "REVERSE" + ] + }, + { + "name": "Taeyang", + "hand": [ + "REVERSE", + "REVERSE", + "REVERSE", + "SKIP", + "SKIP" + ] + }, + { + "name": "T.O.P", + "hand": [ + "PASS", + "PASS", + "SKIP", + "SKIP", + "SKIP" + ] + } + ], + "loser": 3 + }, + { + "deck": [ + "SKIP", + "REVERSE", + "REVERSE", + "REVERSE", + "REVERSE", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "DRAW_TWO", + "REVERSE", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "REVERSE", + "SKIP", + "REVERSE", + "REVERSE", + "PASS", + "SKIP", + "REVERSE", + "PASS", + "PASS", + "REVERSE", + "REVERSE", + "SKIP", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "DRAW_TWO", + "SKIP", + "PASS", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "SKIP", + "SKIP", + "SKIP", + "PASS", + "SKIP", + "PASS", + "SKIP", + "PASS", + "SKIP", + "PASS", + "PASS", + "PASS", + "SKIP", + "REVERSE", + "REVERSE", + "SKIP", + "REVERSE", + "DRAW_TWO", + "DRAW_TWO", + "REVERSE", + "REVERSE", + "REVERSE", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "SKIP", + "REVERSE", + "PASS", + "PASS", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "SKIP", + "REVERSE", + "PASS", + "REVERSE" + ], + "players": [ + { + "name": "Rei", + "hand": [ + "SKIP", + "PASS", + "SKIP", + "REVERSE", + "REVERSE" + ] + }, + { + "name": "Liz", + "hand": [ + "PASS", + "REVERSE", + "SKIP", + "REVERSE", + "DRAW_TWO" + ] + }, + { + "name": "Leeseoo", + "hand": [ + "PASS", + "PASS", + "PASS", + "PASS", + "SKIP" + ] + }, + { + "name": "Gaeul", + "hand": [ + "SKIP", + "SKIP", + "DRAW_TWO", + "REVERSE", + "SKIP" + ] + } + ], + "loser": 2 + } +] diff --git a/solution/H10/src/graderPublic/java/h10/CardGames.java b/solution/H10/src/graderPublic/java/h10/CardGames.java new file mode 100644 index 0000000..1509911 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/CardGames.java @@ -0,0 +1,49 @@ +package h10; + +import h10.assertions.Links; +import h10.util.MockList; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; + +import java.util.List; + +/** + * Utility class for card games. + * + * @author Nhan Huynh + */ +public final class CardGames { + + /** + * Prevent instantiation of this utility class. + */ + private CardGames() { + } + + /** + * Creates a new card game from the given players and card deck. + * + * @param players the players to create the game with + * @param cardDeck the card deck to create the game with + * @return the new card game + */ + public static CardGame create(List players, List cardDeck) { + MyList playerList = new MockList<>(); + players.forEach(playerList::add); + MyList cardList = new MockList<>(); + cardDeck.forEach(cardList::add); + return new CardGame(playerList, cardList); + } + + /** + * Creates a new card game player. + * + * @param name the name of the player + * @return the new card game player + */ + public static CardGamePlayer createPlayer(String name) { + CardGamePlayer player = new CardGamePlayer(name); + FieldLink hand = Links.getField(CardGamePlayer.class, "hand"); + hand.set(player, new MockList<>()); + return player; + } +} diff --git a/solution/H10/src/graderPublic/java/h10/DoublyLinkedLists.java b/solution/H10/src/graderPublic/java/h10/DoublyLinkedLists.java new file mode 100644 index 0000000..1abc602 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/DoublyLinkedLists.java @@ -0,0 +1,35 @@ +package h10; + +import h10.util.ListItems; + +import java.util.List; + +/** + * Utility class for doubly linked lists. + * + * @author Nhan Huynh + */ +public final class DoublyLinkedLists { + + /** + * Prevent instantiation of this utility class. + */ + private DoublyLinkedLists() { + } + + /** + * Creates a new doubly linked list from the given elements. + * + * @param elements the elements to create the list from + * @param The type of the elements. + * @return the new doubly linked list from the given elements + */ + public static DoublyLinkedList create(List elements) { + ListItem head = ListItems.toItems(elements); + DoublyLinkedList list = new DoublyLinkedList<>(); + list.head = head; + list.tail = ListItems.itemStream(head).reduce((a, b) -> b).orElse(null); + list.size = elements.size(); + return list; + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java new file mode 100644 index 0000000..8c97b70 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_1_1_TestsPublic.java @@ -0,0 +1,88 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonConverters; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.1.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.1 | Liste von Spielern erstellen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_1_TestsPublic extends H10_Tests { + + /** + * The converters for the JSON parameters. + */ + public static final Map> CONVERTERS = Map.of( + "names", node -> JsonConverters.toList(node, JsonNode::asText) + ); + + @Override + public Class getClassType() { + return ListItemExamples.class; + } + + @Override + public String getMethodName() { + return "createPlayerListFromNames"; + } + + @Override + public List> getMethodParameters() { + return List.of(String[].class); + } + + @DisplayName("Die Liste wird korrekt erstellt und zurückgegeben. Jedes Listenelement verweist korrekt auf den vorherigen und nächsten Spieler, sofern dieser existiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_1_1.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) { + List expected = parameters.get("names"); + Context context = contextBuilder() + .add("names", expected.toString()) + .add("Expected list", expected.toString()) + .build(); + + // Method to test + ListItem actual = ListItemExamples.createPlayerListFromNames(expected.toArray(String[]::new)); + + // Check order of elements + TutorAssertions.assertEquals(expected, actual, CardGamePlayer::getName, context); + + // Check references + Iterator expectedIterator = expected.iterator(); + Iterator> playerIterator = ListItems.itemIterator(actual); + ListItem previous = null; + while (expectedIterator.hasNext() && playerIterator.hasNext()) { + expectedIterator.next(); + ListItem actualPlayer = playerIterator.next(); + + if (previous != null) { + ListItem currentPrevious = previous; + Assertions2.assertEquals(previous.next.key.getName(), actualPlayer.key.getName(), context, + result -> "The next player of %s should be %s." + .formatted(currentPrevious.key.getName(), actualPlayer.key.getName())); + } + previous = actualPlayer; + } + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java new file mode 100644 index 0000000..f82d0fd --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_1_4_TestsPublic.java @@ -0,0 +1,48 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.1.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.1.3 | Vorkommen der Karte SKIP zählen - mit Iterator") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_1_4_TestsPublic extends H10_1_CountSkipCards_Tests { + + public static final Map> CONVERTERS = Map.of( + "deck", node -> JsonConverters.toList(node, JsonConverters::toPlayingCard), + "skips", JsonNode::asInt + ); + + @Override + protected String getImplementationType() { + return "Iterator"; + } + + @Override + public List> getMethodParameters() { + return List.of(List.class); + } + + @DisplayName("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.") + @Override + @ParameterizedTest + @JsonParameterSetTest(value = "H10_1_CountSkipCards.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) throws Throwable { + assertResult(parameters); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java b/solution/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java new file mode 100644 index 0000000..cf35709 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_1_CountSkipCards_Tests.java @@ -0,0 +1,90 @@ +package h10; + +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.Assertions; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +/** + * Defines the tests for {@code countSkipCardsXYZ} in the class {@code ListItemExamples}. + * + *

The class which implements this abstract class should override the method {@code testResult} and annotate it + * with the {@code @ParameterizedTest} and {@code @JsonParameterSetTest} annotations. + * + *

Use the following schema: + *

{@code
+ *      public class XYZ_Tests extends H10_1_CountSkipCards_Tests {
+ *
+ *          public static final Map> CONVERTERS = Map.of(
+ *              "deck", node -> ...,
+ *               "skips", JsonNode::asInt
+ *          );
+ *
+ *         protected abstract String getImplementationType() {
+ *          return ...; // "Recursive" or "Iterative" or "Iterator"
+ *         }
+ *
+ *         @ParameterizedTest
+ *         @JsonParameterSetTest(value = "H10_1_CountSkipCards.json", customConverters = CUSTOM_CONVERTERS)
+ *         @Override
+ *         void testResult(JsonParameterSet parameters) throws Throwable {
+ *         super.testResult(parameters);
+ *         }
+ *      }
+ *  }
+ * + * @author Nhan Huynh + */ +public abstract class H10_1_CountSkipCards_Tests extends H10_Tests { + + + @Override + public Class getClassType() { + return ListItemExamples.class; + } + + /** + * Returns the implementation type for the method to test which is either recursive or iterative or using + * iterators. + * + * @return the implementation type for the method to test + */ + protected abstract String getImplementationType(); + + @Override + public String getMethodName() { + if (!getImplementationType().equals("Recursive") + && !getImplementationType().equals("Iterative") + && !getImplementationType().equals("Iterator") + ) { + Assertions.fail("The implementation type must be either Recursive or Iterative or Iterator."); + } + + return "countSkipCards" + getImplementationType(); + } + + /** + * Asserts the result of the method. + * @param parameters the parameters for the test method + * @throws Throwable if an error occurs + */ + void assertResult(JsonParameterSet parameters) throws Throwable { + Object deck = parameters.get("deck"); + int expectedSkips = parameters.get("skips"); + Context context = contextBuilder() + .add("Deck", (deck instanceof ListItem items ? ListItems.stream(items).toList() : deck).toString()) + .add("Expected number of skips", expectedSkips) + .build(); + + MethodLink method = getMethod(); + int actualSkips = method.invokeStatic(deck); + + Assertions2.assertEquals(expectedSkips, actualSkips, context, + result -> "The number of SKIP cards in the deck is incorrect."); + } + + abstract void testResult(JsonParameterSet parameters) throws Throwable; +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java new file mode 100644 index 0000000..5dec7c9 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_2_1_TestsPublic.java @@ -0,0 +1,65 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.1 | Ist dieses Element bereits in der Liste?") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_1_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "list", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "key", JsonNode::asInt, + "index", JsonNode::asInt + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "findFirstHelper"; + } + + @Override + public List> getMethodParameters() { + return List.of(ListItem.class, Object.class, int.class); + } + + @DisplayName("Die Methode gibt den Index des ersten Vorkommens des Elements zurück, falls es in der Liste enthalten ist. Andernfalls wird -1 zurückgegeben.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_1.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("list"); + int key = parameters.get("key"); + int index = parameters.get("index"); + Context context = contextBuilder() + .add("List", list.toString()) + .add("Key", key) + .add("Expected index", index) + .build(); + int actual = list.findFirst(key); + Assertions2.assertEquals(index, actual, context, result -> "Index of first occurrence mismatch."); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java new file mode 100644 index 0000000..9aaedbe --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_2_2_TestsPublic.java @@ -0,0 +1,66 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.2 | Auf ein Element in der Liste zugreifen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_2_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "index", JsonNode::asInt, + "element", JsonNode::asInt, + "searchFromStart", JsonNode::asBoolean + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "getListItem"; + } + + @Override + public List> getMethodParameters() { + return List.of(int.class); + } + + @DisplayName("Die Methode gibt das Element an der angegebenen Position zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_2_Position.json", customConverters = CUSTOM_CONVERTERS) + void testPositions(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + int element = parameters.get("element"); + Context context = contextBuilder() + .add("List", list.toString()) + .add("Index", index) + .add("Element to get", element) + .build(); + int actual = list.get(index); + Assertions2.assertEquals(element, actual, context, result -> "Element at the index %s mismatch".formatted(index)); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java new file mode 100644 index 0000000..8514f5d --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_2_3_TestsPublic.java @@ -0,0 +1,126 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.3 | Ein Element hinzufügen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_3_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "index", JsonNode::asInt, + "key", JsonNode::asInt, + "expected", node -> JsonConverters.toList(node, JsonNode::asInt), + "size", JsonNode::asInt + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "add"; + } + + @Override + public List> getMethodParameters() { + return List.of(int.class, Object.class); + } + + @DisplayName("Fall 1: Die Liste ist leer wurde korrekt implementiert.") + @Test + void testEmptyList() { + DoublyLinkedList list = new DoublyLinkedList<>(); + int element = 1; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to add", element) + .add("Expected list after adding", List.of(element)) + .build(); + list.add(element); + + Assertions2.assertEquals(1, list.head.key, context, result -> "Head key mismatch."); + Assertions2.assertEquals(1, list.tail.key, context, result -> "Tail key mismatch."); + Assertions2.assertSame(list.head, list.tail, context, result -> "Head and tail should be the same."); + Assertions2.assertNull(list.head.prev, context, result -> "Head prev should be null."); + Assertions2.assertNull(list.head.next, context, result -> "Tail next should be null."); + } + + @DisplayName("Fall 3: Neues Element an den Anfang der Liste wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Start.json", customConverters = CUSTOM_CONVERTERS) + void testStart(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int element = parameters.get("key"); + List expected = parameters.get("expected"); + int index = 0; + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .add("Expected list after adding", expected.toString()) + .build(); + + list.add(index, element); + + // Check elements + TutorAssertions.assertEquals(expected, list.head, context); + + // Check references + Assertions2.assertSame(list.head.next, items.getFirst(), context, result -> "Head next mismatch."); + Assertions2.assertNull(list.head.prev, context, result -> "Head does not have a previous item."); + Assertions2.assertSame(items.getFirst().prev, list.head, context, + result -> "The successor of the head does not have the head as the previous item."); + } + + @DisplayName("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_3_Exception.json", customConverters = CUSTOM_CONVERTERS) + void testIndexOutOfBoundsException(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + int index = parameters.get("index"); + int element = parameters.get("key"); + + Context context = Assertions2.contextBuilder() + .add("List", list.toString()) + .add("Index to add", index) + .add("Element to add", element) + .build(); + + Assertions2.assertThrows( + IndexOutOfBoundsException.class, + () -> list.add(index, element), + context, + result -> "List with size %s should throw an index out of bounds exception for index %s." + .formatted(list.size, index) + ); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java new file mode 100644 index 0000000..f329c9a --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_2_4_TestsPublic.java @@ -0,0 +1,130 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.assertions.TutorAssertions; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.4. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.4 | Ein Element entfernen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_4_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = new HashMap<>( + Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt), + "element", JsonNode::asInt, + "expected", node -> JsonConverters.toList(node, JsonNode::asInt), + "size", JsonNode::asInt + ) + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "removeListItem"; + } + + @Override + public List> getMethodParameters() { + return List.of(ListItem.class); + } + + @DisplayName("Der Fall 1 wurde korrekt implementiert.") + @Test + void testCase1() throws Throwable { + ListItem item = new ListItem<>(1); + DoublyLinkedList list = new DoublyLinkedList<>(); + list.head = item; + list.tail = item; + list.size = 1; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", item) + .add("Expected list after removal", List.of()) + .build(); + + int removed = getMethod().invoke(list, item); + + Assertions2.assertEquals(item.key, removed, context, + result -> "Returned value should be the key of the removed item"); + Assertions2.assertNull(list.head, context, result -> "Head should be null"); + Assertions2.assertNull(list.tail, context, result -> "Tail should be null"); + } + + @DisplayName("Der Fall 4 wurde korrekt implementiert.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_Case4.json", customConverters = CUSTOM_CONVERTERS) + void testCase4(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int key = parameters.get("key"); + ListItem toRemove = items.stream().filter(item -> item.key.equals(key)).findFirst().orElseThrow(); + ListItem prev = toRemove.prev; + ListItem next = toRemove.next; + List expected = parameters.get("expected"); + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", toRemove) + .add("Expected list after removal", expected.toString()) + .build(); + + int removed = getMethod().invoke(list, toRemove); + Assertions2.assertEquals(toRemove.key, removed, context, + result -> "Returned value should be the key of the removed item"); + TutorAssertions.assertEquals(expected, list.head, context); + + // Check references + Assertions2.assertSame(next, prev.next, context, result -> "removed.next != removed.prev.next"); + Assertions2.assertSame(prev, next.prev, context, result -> "removed.prev != removed.next.prev"); + } + + @DisplayName("Das entfernte Element verweist immernoch auf seine Nachbarn.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_4_References.json", customConverters = CUSTOM_CONVERTERS) + void testReference(JsonParameterSet parameters) throws Throwable { + DoublyLinkedList list = parameters.get("input"); + List> items = ListItems.itemStream(list.head).toList(); + int key = parameters.get("key"); + ListItem toRemove = items.stream().filter(item -> item.key.equals(key)).findFirst().orElseThrow(); + ListItem prev = toRemove.prev; + ListItem next = toRemove.next; + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Element to remove", toRemove) + .build(); + + getMethod().invoke(list, toRemove); + + // Check references + Assertions2.assertSame(prev, toRemove.prev, context, result -> "removed.prev != removed.prev"); + Assertions2.assertSame(next, toRemove.next, context, result -> "removed.next != removed.next"); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java new file mode 100644 index 0000000..048d20f --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_2_5_TestsPublic.java @@ -0,0 +1,66 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H10.2.5. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.2.5 | Alle Elemente entfernen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_2_5_TestsPublic extends H10_Tests { + + public static final Map> CONVERTERS = Map.of( + "input", node -> JsonConverters.toDoublyLinkedList(node, JsonNode::asInt) + ); + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "clear"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + @DisplayName("Nach einem Aufruf von clear() ist die Liste leer. Insbesondere sind head und tail auf null gesetzt, und die Größe der Liste ist 0.") + @ParameterizedTest + @JsonParameterSetTest(value = "H10_2_5.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) { + DoublyLinkedList list = parameters.get("input"); + + Context context = contextBuilder() + .add("List", list.toString()) + .add("Expected list after clear()", List.of()) + .add("Expected size after clear()", 0) + .build(); + + list.clear(); + + Assertions2.assertNull(list.head, context, result -> "Head should be null after clear()"); + Assertions2.assertNull(list.tail, context, result -> "Tail should be null after clear()"); + Assertions2.assertEquals(0, list.size(), context, result -> "Size should be 0 after clear()"); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java new file mode 100644 index 0000000..2520181 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_3_1_TestsPublic.java @@ -0,0 +1,156 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import h10.util.ListItems; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.List; + +/** + * Defines the public tests for H10.3.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.1 | Das nächste Element zurückgeben") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_1_TestsPublic extends H10_Tests { + + @Override + public Class getClassType() { + return DoublyLinkedList.class; + } + + @Override + public String getMethodName() { + return "cyclicIterator"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + @DisplayName("Die Methode hasNext() gibt korrekt an, ob es ein nächstes Element gibt.") + @Test + void testHasNext() { + List> testCases = List.of( + List.of(1, 2, 3), + List.of(1), + List.of() + ); + testCases.forEach(elements -> { + DoublyLinkedList list = DoublyLinkedLists.create(elements); + BidirectionalIterator it = list.cyclicIterator(); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", elements.isEmpty() ? "No elements left" : "null") + .add("Next element", elements.isEmpty() ? "No elements left" : elements.getFirst()) + .build(); + + if (elements.isEmpty()) { + Assertions2.assertFalse(it.hasNext(), context, + result -> "hasNext() should return false if there are no elements left."); + } else { + Assertions2.assertTrue(it.hasNext(), context, + result -> "hasNext() should return true if there are elements left."); + } + }); + } + + @DisplayName("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextEmpty() { + List elements = List.of(1, 2, 3); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", "null") + .add("Next element", elements.getFirst()) + .build(); + + Assertions2.assertEquals(elements.getFirst(), it.next(), context, + result -> "next() should return the first element of the list."); + Assertions2.assertEquals(items, it.p, context, result -> "p should point to the first element of the list."); + } + + @DisplayName("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextEnd() { + List elements = List.of(1, 2, 3); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + List> refs = ListItems.itemStream(items).toList(); + + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + it.p = refs.getLast(); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", elements.getLast()) + .add("Next element", elements.getFirst()) + .build(); + + Assertions2.assertEquals(elements.getFirst(), it.next(), context, + result -> "next() should return the first element of the list."); + Assertions2.assertEquals(items, it.p, context, result -> "p should point to the first element of the list."); + } + + @DisplayName("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.") + @Test + void testNextMiddle() { + List elements = List.of(1, 2, 3, 4, 5); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + List> refs = ListItems.itemStream(items).toList(); + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + int start = 1; + int end = elements.size() - 1; + for (int i = start; i < end; i++) { + it.p = refs.get(i - 1); + + Context context = contextBuilder() + .add("List", elements.toString()) + .add("Current element", elements.get(i - 1)) + .add("Next element", elements.get(i)) + .build(); + + int currentIndex = i; + Assertions2.assertEquals(elements.get(i), it.next(), context, + result -> "next() result mismatch at index %s.".formatted(currentIndex)); + Assertions2.assertEquals(refs.get(i), it.p, context, + result -> "p reference mismatch at index %s.".formatted(currentIndex)); + } + } + + @DisplayName("Die Methode next() setzt das Attribut calledRemove auf false.") + @Test + void testCalledRemove() { + List elements = List.of(1, 2, 3, 4, 5); + DoublyLinkedList list = DoublyLinkedLists.create(elements); + ListItem items = list.head; + DoublyLinkedList.CyclicIterator it = (DoublyLinkedList.CyclicIterator) list.cyclicIterator(); + it.p = items; + it.calledRemove = true; + + Context context = contextBuilder() + .add("List", elements) + .add("Current element", elements.getFirst()) + .add("Next element", elements.get(1)) + .add("calledRemove", true) + .build(); + + Assertions2.call(it::next, context, result -> "Expected next() to be called without exception."); + Assertions2.assertFalse(it.calledRemove, context, result -> "calledRemove should be set to false after call."); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java b/solution/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java new file mode 100644 index 0000000..a59a6c2 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_3_3_TestsPublic.java @@ -0,0 +1,206 @@ +package h10; + +import h10.assertions.TestConstants; +import h10.rubric.H10_Tests; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.ArrayList; +import java.util.List; + +/** + * Defines the public tests for H10.3.3. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H10.3.3 | Verlierer des Spiels bestimmen") +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H10_3_3_TestsPublic extends H10_Tests { + + @Override + public Class getClassType() { + return CardGame.class; + } + + @Override + public String getMethodName() { + return "doTurn"; + } + + @Override + public List> getMethodParameters() { + return List.of(); + } + + /** + * Converts a MyList to a List. + * + * @param myList the MyList to convert + * @param the type of the elements in the list. + * + * @return the converted List. + */ + protected List fromMyList(MyList myList) { + List list = new ArrayList<>(); + for (int i = 0; i < myList.size(); i++) { + list.add(myList.get(i)); + } + return list; + } + + @DisplayName("Bei einem SKIP wird der nächste Spieler übersprungen.") + @Test + void testSkip() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.SKIP); + playerOne.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.SKIP); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + + CardGame game = CardGames.create(players, deck); + + int nextHandSize = playerTwo.getHandSize(); + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerTwo) + .add("Playing card", PlayingCard.SKIP) + .build(); + + // Current player turn + getMethod().invoke(game); + // Check if skip is correctly set + Assertions2.assertTrue(game.skipNextPlayer, context, result -> "The game should skip the next player."); + + // Next player turn + getMethod().invoke(game); + + // Check if the next player is skipped + Assertions2.assertSame(playerTwo, game.currentPlayer, context, + result -> "The current player should be the next player."); + + Assertions2.assertFalse(game.skipNextPlayer, context, + result -> "Skip player should be reset after skipping the next player."); + Assertions2.assertEquals(nextHandSize, playerTwo.getHandSize(), context, + result -> "The next player should not play any cards."); + } + + @DisplayName("Bei einer REVERSE-Karte wird die Richtung des Iterators umgekehrt.") + @Test + void testReverse() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + playerOne.takeCard(PlayingCard.REVERSE); + playerOne.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.SKIP); + + playerFour.takeCard(PlayingCard.SKIP); + playerFour.takeCard(PlayingCard.SKIP); + + playerTwo.takeCard(PlayingCard.SKIP); + playerTwo.takeCard(PlayingCard.SKIP); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + p.takeCard(PlayingCard.PASS); + }); + + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList).flatMap(List::stream). + toList(); + CardGame game = CardGames.create(players, deck); + + int successorPlayerHandSize = playerTwo.getHandSize(); + int predecessorPlayerHandSize = playerFour.getHandSize(); + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Next player", playerFour) + .add("Playing card", PlayingCard.REVERSE) + .build(); + + // Current player turn + getMethod().invoke(game); + + // Check if skip is correctly set + Assertions2.assertTrue(game.reverseDirection, context, result -> "The game should reverse the direction."); + + // Last player turn + getMethod().invoke(game); + Assertions2.assertSame(playerFour, game.currentPlayer, context, + result -> "The current player should be the last player."); + Assertions2.assertEquals(successorPlayerHandSize, playerTwo.getHandSize(), context, + result -> "The last player should not play any card."); + Assertions2.assertEquals(predecessorPlayerHandSize - 1, playerFour.getHandSize(), context, + result -> "The last player should play one card."); + } + + @DisplayName("Spieler, die keine Karten mehr auf der Hand haben, werden aus dem Spiel entfernt.") + @Test + void testNoCards() throws Throwable { + CardGamePlayer playerOne = CardGames.createPlayer("Lisa"); + CardGamePlayer playerTwo = CardGames.createPlayer("Jennie"); + CardGamePlayer playerThree = CardGames.createPlayer("Rosie"); + CardGamePlayer playerFour = CardGames.createPlayer("Jisoo"); + List players = List.of(playerOne, playerTwo, playerThree, playerFour); + + players.forEach(p -> { + p.takeCard(PlayingCard.PASS); + }); + List deck = players.stream() + .map(player -> player.hand) + .map(this::fromMyList) + .flatMap(List::stream) + .toList(); + CardGame game = CardGames.create(players, deck); + + + Context context = contextBuilder() + .add("Players", players) + .add("Deck", deck) + .add("Current player", playerOne) + .add("Playing card", PlayingCard.PASS) + .build(); + + int numberOfPlayers = players.size(); + // Current player turn + getMethod().invoke(game); + Assertions2.assertEquals(0, playerOne.getHandSize(), context, result -> "The player should not have any card."); + Assertions2.assertEquals(numberOfPlayers - 1, game.players.size(), + context, result -> "The player should be removed from the game."); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java b/solution/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java new file mode 100644 index 0000000..91bf00d --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/H10_RubricProviderPublic.java @@ -0,0 +1,18 @@ +package h10; + +import h10.rubric.H10_RubricProvider; + +/** + * A public rubric provider for H10. + * + * @author Nhan Huynh + */ +public class H10_RubricProviderPublic extends H10_RubricProvider { + + /** + * Constructs a new public rubric provider. + */ + public H10_RubricProviderPublic() { + super(true); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/JsonConverters.java b/solution/H10/src/graderPublic/java/h10/JsonConverters.java new file mode 100644 index 0000000..641f8c0 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/JsonConverters.java @@ -0,0 +1,107 @@ +package h10; + +import com.fasterxml.jackson.databind.JsonNode; +import h10.assertions.Links; +import h10.util.ListItems; +import h10.util.MockList; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +/** + * Utility class for working with JSON data. + * + * @author Nhan Huynh + */ +public final class JsonConverters extends org.tudalgo.algoutils.tutor.general.json.JsonConverters { + + /** + * Prevent instantiation of this utility class. + */ + private JsonConverters() { + } + + /** + * Converts the given JSON node to a list of items using the given mapper. + * + * @param node the JSON node to convert + * @param mapper the mapper to use for mapping the items + * @param the type of the items in the list + * @return the head of the list item created from the JSON node + */ + public static ListItem toItems(JsonNode node, Function mapper) { + if (!node.isArray()) { + throw new IllegalArgumentException("Node is not an array"); + } + return ListItems.toItems(toList(node, mapper)); + } + + /** + * Converts the given JSON node to a playing card. + * + * @param node the JSON node to convert + * @return the playing card represented by the JSON node + */ + public static PlayingCard toPlayingCard(JsonNode node) { + if (!node.isTextual()) { + throw new IllegalArgumentException("Node is not a textual"); + } + String value = node.asText().toUpperCase(); + return Arrays.stream(PlayingCard.values()).filter(card -> card.name().equals(value)).findFirst().orElseThrow(); + } + + /** + * Converts the given JSON node to a deck of playing cards. + * + * @param node the JSON node to convert + * @return the deck of playing cards represented by the JSON node + */ + public static List toDeck(JsonNode node) { + if (!node.isArray()) { + throw new IllegalArgumentException("Node is not an array"); + } + return toList(node, JsonConverters::toPlayingCard); + } + + /** + * Converts the given JSON node to a player. + * + * @param node the JSON node to convert + * @return the player represented by the JSON node + */ + public static CardGamePlayer toPlayer(JsonNode node) { + if (!node.isObject()) { + throw new IllegalArgumentException("Node is not an object"); + } + CardGamePlayer player = new CardGamePlayer(node.get("name").asText()); + FieldLink hand = Links.getField(CardGamePlayer.class, "hand"); + hand.set(player, MockList.of(toList(node.get("hand"), JsonConverters::toPlayingCard))); + return player; + } + + /** + * Converts the given JSON node to a doubly linked list. + * + * @param node the JSON node to convert + * @param mapper the mapper to use for mapping the items + * @param the type of the items in the list + * @return the doubly linked list represented by the JSON nodeo + */ + public static DoublyLinkedList toDoublyLinkedList(JsonNode node, Function mapper) { + if (!node.isArray()) { + throw new IllegalArgumentException("Node is not an array"); + } + DoublyLinkedList list = new DoublyLinkedList<>(); + list.head = toItems(node, mapper); + list.tail = list.head; + int size = 0; + for (ListItem current = list.head; current != null; current = current.next) { + list.tail = current; + size++; + } + list.size = size; + return list; + } +} diff --git a/solution/H10/src/graderPublic/java/h10/assertions/Links.java b/solution/H10/src/graderPublic/java/h10/assertions/Links.java new file mode 100644 index 0000000..cfeb5a9 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/assertions/Links.java @@ -0,0 +1,109 @@ +package h10.assertions; + +import org.tudalgo.algoutils.tutor.general.assertions.Assertions3; +import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.match.MatcherFactories; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.PackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; + +/** + * Utility class for links to classes and methods. + * + * @author Nhan Huynh + */ +public final class Links { + + /** + * Matcher factory for string matchers. + */ + private static final MatcherFactories.StringMatcherFactory STRING_MATCHER_FACTORY = BasicStringMatchers::identical; + + /** + * The package link for the h10 package. + */ + public static final PackageLink PACKAGE = BasicPackageLink.of("h10"); + + /** + * Prevent instantiation of this utility class. + */ + private Links() { + + } + + /** + * Returns the type link for the given class. + * + * @param clazz the class to get the type from + * @return the type link for the given class + */ + public static TypeLink getType(Class clazz) { + return Assertions3.assertTypeExists( + PACKAGE, + STRING_MATCHER_FACTORY.matcher(clazz.getSimpleName()) + ); + } + + /** + * Returns the field link for the given type and field name. + * + * @param type the type to get the field from + * @param methodName the name of the field + * @param matchers the matchers for additional checks to retrieve the field + * @return the field link for the given type and field name + */ + @SafeVarargs + public static FieldLink getField(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertFieldExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the field link for the given class and field name. + * + * @param clazz the class to get the field from + * @param fieldName the name of the field + * @param matchers the matchers for additional checks to retrieve the field + * @return the field link for the given class and field name + */ + @SafeVarargs + public static FieldLink getField(Class clazz, String fieldName, Matcher... matchers) { + return getField(getType(clazz), fieldName, matchers); + } + + /** + * Returns the method link for the given type and method name. + * + * @param type the type to get the method from + * @param methodName the name of the method + * @param matchers the matchers for additional checks to retrieve the method + * @return the method link for the given type and method name + */ + @SafeVarargs + public static MethodLink getMethod(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertMethodExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the method link for the given class and method name. + * + * @param clazz the class to get the method from + * @param methodName the name of the method + * @param matchers the matchers for additional checks to retrieve the method + * @return the method link for the given class and method name + */ + @SafeVarargs + public static MethodLink getMethod(Class clazz, String methodName, Matcher... matchers) { + return getMethod(getType(clazz), methodName, matchers); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/assertions/TestConstants.java b/solution/H10/src/graderPublic/java/h10/assertions/TestConstants.java new file mode 100644 index 0000000..6e29843 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/assertions/TestConstants.java @@ -0,0 +1,26 @@ +package h10.assertions; + +/** + * Constants for tests for configuring test behavior. + * + * @author Nhan Huynh + */ +public final class TestConstants { + + + /** + * Timeout for tests in seconds. + */ + public static final int TEST_TIMEOUT_IN_SECONDS = 2; + + /** + * Skip after first failed test. + */ + public static final boolean SKIP_AFTER_FIRST_FAILED_TEST = true; + + /** + * Prevent instantiation of this utility class. + */ + private TestConstants() { + } +} diff --git a/solution/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java b/solution/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java new file mode 100644 index 0000000..30100a0 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/assertions/TutorAssertions.java @@ -0,0 +1,89 @@ +package h10.assertions; + +import h10.ListItem; +import h10.util.ListItems; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; + +import java.util.Iterator; +import java.util.function.Function; + +/** + * Defines tutor-specific assertions for the h10 package. + * + * @author Nhan Huynh + */ +public final class TutorAssertions { + + /** + * Prevent instantiation of this utility class. + */ + private TutorAssertions() { + } + + + /** + * Asserts that the given expected elements are equal to the actual elements. + * + * @param expected the expected elements + * @param actual the actual elements + * @param mapper the mapper to convert the actual elements to the expected elements + * @param context the context to use for the assertions + * @param the type of the elements + */ + public static void assertEquals(Iterable expected, ListItem actual, Function mapper, Context context) { + assertEquals(expected, () -> ListItems.stream(actual).map(mapper).map(it -> (Object) it).iterator(), context); + } + + /** + * Asserts that the given expected elements are equal to the actual elements. + * + * @param expected the expected elements + * @param actual the actual elements + * @param context the context to use for the assertions + */ + public static void assertEquals(Iterable expected, ListItem actual, Context context) { + assertEquals(expected, actual, Function.identity(), context); + } + + /** + * Asserts that the given expected elements are equal to the actual elements. + * + * @param expected the expected elements + * @param actual the actual elements + * @param context the context to use for the assertions + */ + public static void assertEquals(Iterable expected, Iterable actual, Context context) { + Iterator itE = expected.iterator(); + Iterator itA = actual.iterator(); + int index = 0; + while (itE.hasNext() && itA.hasNext()) { + int currentIndex = index; + Assertions2.assertEquals(itE.next(), itA.next(), context, + result -> "Element at index " + currentIndex + " does not match"); + index++; + } + + // Check if expected or actual contains more elements + int overflow = 0; + while (itE.hasNext()) { + itE.next(); + overflow++; + } + + if (overflow > 0) { + int currentOverflow = overflow; + Assertions2.fail(context, + result -> "Actual list has %s fewer elements".formatted(currentOverflow)); + } + while (itA.hasNext()) { + itA.next(); + overflow++; + } + if (overflow > 0) { + int currentOverflow = overflow; + Assertions2.fail(context, + result -> "Actual list has %s more elements".formatted(currentOverflow)); + } + } +} diff --git a/solution/H10/src/graderPublic/java/h10/rubric/Builder.java b/solution/H10/src/graderPublic/java/h10/rubric/Builder.java new file mode 100644 index 0000000..df0db38 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/rubric/Builder.java @@ -0,0 +1,16 @@ +package h10.rubric; + +/** + * A builder interface for building objects. + * + * @param the type of object to build + */ +public interface Builder { + + /** + * Builds the object. + * + * @return the built object + */ + T build(); +} diff --git a/solution/H10/src/graderPublic/java/h10/rubric/Criteriable.java b/solution/H10/src/graderPublic/java/h10/rubric/Criteriable.java new file mode 100644 index 0000000..67165a4 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/rubric/Criteriable.java @@ -0,0 +1,19 @@ +package h10.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; + +/** + * An object that implements this interface indicates that it can be converted to a {@link Criterion} which means + * it is gradable. + * + * @author Nhan Huynh + */ +public interface Criteriable { + + /** + * Returns the criterion that represents this object. + * + * @return the criterion that represents this object + */ + Criterion getCriterion(); +} diff --git a/solution/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java b/solution/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java new file mode 100644 index 0000000..32ef4a8 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/rubric/H10_RubricProvider.java @@ -0,0 +1,238 @@ +package h10.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Provides the rubric for H10. + * + * @author Nhan Huynh + */ +public abstract class H10_RubricProvider implements RubricProvider { + + /** + * Defines the subtask H10.1.1 for task H10.1. + */ + private static final Subtask H10_1_1 = Subtask.builder() + .description("H10.1.1 | Liste von Spielern erstellen") + .testClassName("h10.H10_1_1_Tests") + .criterion("Die Liste wird korrekt erstellt und zurückgegeben. Jedes Listenelement verweist korrekt auf den vorherigen und nächsten Spieler, sofern dieser existiert.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.1.2 for task H10.1. + */ + private static final Subtask H10_1_2 = Subtask.builder() + .description("H10.1.2 | Vorkommen der Karte SKIP zählen - iterativ") + .testClassName("h10.H10_1_2_Tests") + .criterion("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.", false, "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion", "testLoops") + .build(); + + /** + * Defines the subtask H10.1.3 for task H10.1. + */ + private static final Subtask H10_1_3 = Subtask.builder() + .description("H10.1.3 | Vorkommen der Karte SKIP zählen - rekursiv") + .testClassName("h10.H10_1_3_Tests") + .criterion("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.", false, "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Schleifen", "testRecursions") + .build(); + + /** + * Defines the subtask H10.1.4 for task H10.1. + */ + private static final Subtask H10_1_4 = Subtask.builder() + .description("H10.1.4 | Vorkommen der Karte SKIP zählen - mit Iterator") + .testClassName("h10.H10_1_4_Tests") + .criterion("Die Anzahl der Karten des Typs SKIP wird korrekt gezählt und zurückgegeben.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion", "testLoops") + .build(); + + /** + * Defines the task H10.1. + */ + private static final Task H10_1 = Task.builder() + .description("H10.1 | Beispiele mit Klasse ListItem") + .subtasks(H10_1_1, H10_1_2, H10_1_3, H10_1_4) + .build(); + + + /** + * Defines the subtask H10.2.1 for task H10.2. + */ + private static final Subtask H10_2_1 = Subtask.builder() + .description("H10.2.1 | Ist dieses Element bereits in der Liste?") + .testClassName("h10.H10_2_1_Tests") + .criterion("Die Methode gibt den Index des ersten Vorkommens des Elements zurück, falls es in der Liste enthalten ist. Andernfalls wird -1 zurückgegeben.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Schleifen", "testRecursions") + .build(); + + /** + * Defines the subtask H10.2.2 for task H10.2. + */ + private static final Subtask H10_2_2 = Subtask.builder() + .description("H10.2.2 | Auf ein Element in der Liste zugreifen") + .testClassName("h10.H10_2_2_Tests") + .criterion("Die Methode gibt das Element an der angegebenen Position zurück.", "testPositions", JsonParameterSet.class) + .criterion("Die Suche wird in der Liste von vorne oder hinten gestartet, je nachdem, welcher Weg kürzer ist.", false, "testPath", JsonParameterSet.class) + .criterion("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.", false, "testException", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Rekursion", "testLoops") + .build(); + + /** + * Defines the subtask H10.2.3 for task H10.2. + */ + private static final Subtask H10_2_3 = Subtask.builder() + .description("H10.2.3 | Ein Element hinzufügen") + .testClassName("h10.H10_2_3_Tests") + .criterion("Fall 1: Die Liste ist leer wurde korrekt implementiert.", "testEmptyList") + .criterion("Fall 2: Neues Element an das Ende der Liste wurde korrekt implementiert.", false, "testEnd", JsonParameterSet.class) + .criterion("Fall 3: Neues Element an den Anfang der Liste wurde korrekt implementiert.", "testStart", JsonParameterSet.class) + .criterion("Fall 4: Neues Element in der Mitte der Liste wurde korrekt implementiert.", false, "testMiddle", JsonParameterSet.class) + .criterion("Die Größe der Liste wird um 1 erhöht.", false, "testSize", JsonParameterSet.class) + .criterion("Falls die Position nicht existiert, wird eine IndexOutOfBoundsException geworfen.", "testIndexOutOfBoundsException", JsonParameterSet.class) + .criterion("Falls der übergebene key null ist, wird eine IllegalArgumentException geworfen.", false, "testIllegalArgumentException", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.2.4 for task H10.2. + */ + private static final Subtask H10_2_4 = Subtask.builder() + .description("H10.2.4 | Ein Element entfernen") + .testClassName("h10.H10_2_4_Tests") + .criterion("Die Fälle 1 und 4 wurden korrekt implementiert.", Map.of( + "testCase1", List.of(), + "testCase4", List.of(JsonParameterSet.class) + )) + .criterion("Die Fälle 2 und 3 wurden korrekt implementiert.", false, Map.of( + "testCase2", List.of(JsonParameterSet.class), + "testCase3", List.of(JsonParameterSet.class) + )) + .criterion("Die Größe der Liste wird um 1 verringert.", false, "testSize", JsonParameterSet.class) + .criterion("Das entfernte Element verweist immernoch auf seine Nachbarn.", "testReference", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.2.5 for task H10.2. + */ + private static final Subtask H10_2_5 = Subtask.builder() + .description("H10.2.5 | Alle Elemente entfernen") + .testClassName("h10.H10_2_5_Tests") + .criterion("Nach einem Aufruf von clear() ist die Liste leer. Insbesondere sind head und tail auf null gesetzt, und die Größe der Liste ist 0.", "testResult", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the task H10.2. + */ + private static final Task H10_2 = Task.builder() + .description("H10.2 | DoublyLinkedList") + .subtasks(H10_2_1, H10_2_2, H10_2_3, H10_2_4, H10_2_5) + .build(); + + /** + * Defines the subtask H10.3.1 for task H10.3. + */ + private static final Subtask H10_3_1 = Subtask.builder() + .description("H10.3.1 | Das nächste Element zurückgeben") + .testClassName("h10.H10_3_1_Tests") + .criterion("Die Methode hasNext() gibt korrekt an, ob es ein nächstes Element gibt.", "testHasNext") + .criterion("Die Methode next() gibt das nächste Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.", Map.of( + "testNextEmpty", List.of(), + "testNextEnd", List.of(), + "testNextMiddle", List.of() + )) + .criterion("Die Methode next() setzt das Attribut calledRemove auf false.", "testCalledRemove") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.3.2 for task H10.3. + */ + private static final Subtask H10_3_2 = Subtask.builder() + .description("H10.3.2 | Das vorherige Element zurückgeben") + .testClassName("h10.H10_3_2_Tests") + .criterion("Die Methode hasPrevious() gibt korrekt an, ob es ein vorheriges Element gibt.", false, "testHasPrevious") + .criterion("Die Methode previous() gibt das vorherige Element des Iterators zurück. Der Pointer p zeigt auf das neue Listenelement.", false, Map.of( + "testPreviousEmpty", List.of(), + "testPreviousEnd", List.of(), + "testNextMiddle", List.of() + )) + .criterion("Die Methode previous() setzt das Attribut calledRemove auf false.", false, "testCalledRemove") + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the subtask H10.3.3 for task H10.3. + */ + private static final Subtask H10_3_3 = Subtask.builder() + .description("H10.3.3 | Verlierer des Spiels bestimmen") + .testClassName("h10.H10_3_3_Tests") + .criterion("Bei einem SKIP wird der nächste Spieler übersprungen.", "testSkip") + .criterion("Bei einer REVERSE-Karte wird die Richtung des Iterators umgekehrt.", "testReverse") + .criterion("Wurde im letzten Zug eine DRAW_TWO-Karte gespielt, so muss der nächste Spieler zwei Karten ziehen, sofern er nicht auch eine DRAW_TWO-Karte spielt.", false, Map.of( + "testDrawTwoLastTurnNoDrawTwo", List.of(), + "testDrawTwoLastTurnDrawTwo", List.of() + )) + .criterion("Wurden in den vorherigen Zügen mehrere DRAW_TWO-Karten gespielt, so erhöht sich die Anzahl der zu ziehenden Karten entsprechend.", false, "testDrawTwoMultiple") + .criterion("Spieler, die keine Karten mehr auf der Hand haben, werden aus dem Spiel entfernt.", "testNoCards") + .criterion("Der Spieler, der als letztes Karten in der Hand hat, wird korrekt bestimmt und zurückgegeben.", false, "testLoser", JsonParameterSet.class) + .requirement("Verbindliche Anforderungen: Unerlaubte Verwendung von Datenstrukturen", "testDataStructure") + .build(); + + /** + * Defines the task H10.3. + */ + private static final Task H10_3 = Task.builder() + .description("H10.3 | Zyklischer Iterator über die DoublyLinkedList") + .subtasks(H10_3_1, H10_3_2, H10_3_3) + .build(); + + /** + * Whether the private tests are being graded. + */ + private final boolean publicTests; + + /** + * Constructs a new rubric provider. + * + * @param publicTests whether the private tests are being graded + */ + public H10_RubricProvider(boolean publicTests) { + this.publicTests = publicTests; + } + + /** + * Constructs a new public rubric provider. + */ + public H10_RubricProvider() { + this(true); + } + + @Override + public Rubric getRubric() { + return Rubric.builder() + .title("H10 | Doppelt verkette Listen - %s Tests".formatted(publicTests ? "Public" : "Private")) + .addChildCriteria( + Stream.of(H10_1, H10_2, H10_3) + .map(Task::getCriterion) + .toArray(Criterion[]::new) + ) + .build(); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/rubric/H10_Tests.java b/solution/H10/src/graderPublic/java/h10/rubric/H10_Tests.java new file mode 100644 index 0000000..880cad8 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/rubric/H10_Tests.java @@ -0,0 +1,155 @@ +package h10.rubric; + +import h10.assertions.Links; +import h10.assertions.TestConstants; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.List; + +/** + * Defines a test skeleton for the H10 assignment. + * + *

Use the following schema: + *

{@code
+ *     public class TestClass extends H10_Test {
+ *          public static final Map> CUSTOM_CONVERTERS = Map.of(
+ *              ...
+ *          );
+ *
+ *          @Override
+ *          public Class getClassType() {
+ *              return ...
+ *          }
+ *
+ *          @Override
+ *          public String getMethodName() {
+ *              return "...";
+ *          }
+ *
+ *          @Override
+ *          public List> getMethodParameters() {
+ *              return List.of(...);
+ *          }
+ *
+ *          @ParameterizedTest
+ *          @JsonParameterSetTest(value = "path-to-json-data.json", customConverters = CUSTOM_CONVERTERS)
+ *          void testXYZ(JsonParameterSet parameters) {
+ *              ...
+ *          }
+ *   }
+ * }
+ * + * @author Nhan Huynh + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@TestForSubmission +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public abstract class H10_Tests { + + /** + * The attribute name for custom converters in the JSON parameter set test annotation. + */ + public static final String CUSTOM_CONVERTERS = "CONVERTERS"; + + /** + * The type of the class under test. + */ + private @Nullable TypeLink type; + + /** + * The method under test. + */ + private @Nullable MethodLink method; + + /** + * Configuration for all tests. + */ + @BeforeAll + void globalSetup() { + Assertions.assertNotNull( + getClass().getAnnotation(TestForSubmission.class), + "The test class is not annotated with @TestForSubmission." + ); + + this.type = Links.getType(getClassType()); + this.method = Links.getMethod( + type, + getMethodName(), + Matcher.of(method -> method.typeList().equals(getMethodParametersLink())) + ); + } + + /** + * Returns the class type of the class under test. + * + * @return the class type of the class under test + */ + public abstract Class getClassType(); + + /** + * Returns the name of the method under test. + * + * @return the name of the method under test + */ + public abstract String getMethodName(); + + /** + * Return the parameter types of the method under test. + * + * @return the parameter types of the method under test + */ + public abstract List> getMethodParameters(); + + /** + * Return the parameter types of the method under test. + * + * @return the parameter types of the method under test + */ + public List getMethodParametersLink() { + return getMethodParameters().stream().map(BasicTypeLink::of).toList(); + } + + /** + * Returns the type of the class under test. + * + * @return the type of the class under test + */ + public TypeLink getType() { + if (type == null) { + throw new IllegalStateException("Type not initialized"); + } + return type; + } + + /** + * Returns the method under test. + * + * @return the method under test + */ + public MethodLink getMethod() { + if (method == null) { + throw new IllegalStateException("Method not initialized"); + } + return method; + } + + /** + * Returns a context builder with the method under test as the subject. + * + * @return a context builder with the method under test as the subject + */ + public Context.Builder contextBuilder() { + return Assertions2.contextBuilder().subject(getMethod().reflection()); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/rubric/Subtask.java b/solution/H10/src/graderPublic/java/h10/rubric/Subtask.java new file mode 100644 index 0000000..2e548b4 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/rubric/Subtask.java @@ -0,0 +1,312 @@ +package h10.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Gradable; +import org.sourcegrade.jagr.api.rubric.Grader; +import org.sourcegrade.jagr.api.rubric.JUnitTestRef; +import org.tudalgo.algoutils.tutor.general.jagr.RubricUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/** + * Represents a subtask in a rubric. + * + * @param description a short description of the subtask + * @param criteria the subtasks that must be met to complete the subtask + * @param requirements the requirements that must be met to complete the subtask + * @author Nhan Huynh + */ +public record Subtask( + String description, + List criteria, + List requirements +) implements Criteriable { + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + * + * @return a new subtask builder + */ + public static SubtaskBuilder builder() { + return new SubtaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .minPoints(0) + .addChildCriteria(Stream.concat(criteria.stream(), requirements.stream()).toArray(Criterion[]::new)) + .build(); + } + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + */ + public interface SubtaskBuilder extends Builder { + + /** + * Sets the description of the subtask. + * + * @param description the description of the subtask + * @return this builder instance with the description set + */ + SubtaskBuilder description(String description); + + /** + * Sets the name of the test class that tests this subtask. + * + * @param testClassName the name of the test class that tests this subtask + * @return this builder instance with the test class name set + */ + SubtaskBuilder testClassName(String testClassName); + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodsSignature the signature of the test methods + * @return this builder instance with the criterion added + */ + SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ); + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodsSignature the signature of the test methods + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, Map>> testMethodsSignature) { + return criterion(description, true, testMethodsSignature); + } + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion( + String description, + boolean publicTest, + String testMethodName, + Class... testMethodParameters + ) { + return criterion(description, publicTest, Map.of(testMethodName, List.of(testMethodParameters))); + } + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodName the name of the test method + * @param testMethodSignature the signature of the test method + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, String testMethodName, Class... testMethodSignature) { + return criterion(description, true, testMethodName, testMethodSignature); + } + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodsSignature the signature of the test methods + * @return this builder instance with the requirement added + */ + SubtaskBuilder requirement(String description, Map>> testMethodsSignature); + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * @return this builder instance with the requirement added + */ + default SubtaskBuilder requirement(String description, String testMethodName, Class... testMethodParameters) { + return requirement(description, Map.of(testMethodName, List.of(testMethodParameters))); + } + } + + /** + * A builder for building {@link Subtask} instances. + */ + private static class SubtaskCriteriaBuilderImpl implements SubtaskBuilder { + + /** + * The description of the subtask. + */ + private @NotNull String description = ""; + + /** + * The name of the test class that tests this subtask. + */ + private @NotNull String testClassName = ""; + + /** + * The subtasks of the subtask. + */ + private final List> criteria = new ArrayList<>(); + + /** + * The requirements of the subtask. + */ + private final List> requirements = new ArrayList<>(); + + @Override + public SubtaskBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public SubtaskBuilder testClassName(String testClassName) { + this.testClassName = testClassName; + return this; + } + + /** + * Returns the description of the subtask. + * + * @return the description of the subtask + */ + private @NotNull String getDescription() { + return description; + } + + /** + * Returns a pre-configured criterion builder where the description and grader are set. + * + * @param description the description of the criterion + * @param grader the grader of the criterion + * @return a pre-configured criterion builder with the description and grader set + */ + private Criterion.Builder criterionBuilder(String description, Grader grader) { + return Criterion.builder() + .shortDescription(description) + .grader(grader); + } + + /** + * Returns a pre-configured criterion builder where the description and test reference are set. + * + * @param description the description of the criterion + * @param testRef the test reference of the criterion + * @return a pre-configured criterion builder with the description and test reference set + */ + private Criterion.Builder criterionBuilder(String description, JUnitTestRef testRef) { + return criterionBuilder( + description, + Grader.testAwareBuilder() + .requirePass(testRef) + .pointsFailedMin() + .pointsPassedMax() + .build() + ); + } + + /** + * Creates a criterion supplier with the given description, class name, test methods signature, and points. + * Since the points can only be determined after all subtasks are added, the points are calculated lazily. + * + * @param description the description of the criterion + * @param className the name of the test class that tests this subtask + * @param testMethodsSignature the signature of the test methods + * @param points the points of the criterion + * @return a criterion supplier with the given description, class name, test methods signature, and points + */ + private Supplier criterion( + String description, + String className, + Map>> testMethodsSignature, + Supplier points + ) { + return () -> { + Criterion.Builder builder; + try { + List testRefs = new ArrayList<>(testMethodsSignature.size()); + for (Map.Entry>> entry : testMethodsSignature.entrySet()) { + Method method = Class.forName(className).getDeclaredMethod( + entry.getKey(), + entry.getValue().toArray(Class[]::new) + ); + testRefs.add(JUnitTestRef.ofMethod(method)); + } + builder = criterionBuilder(description, JUnitTestRef.and(testRefs.toArray(JUnitTestRef[]::new))); + } catch (Exception e) { + builder = criterionBuilder(description, RubricUtils.graderPrivateOnly()); + } + int pointsValue = points.get(); + if (pointsValue >= 0) { + builder.minPoints(0); + builder.maxPoints(pointsValue); + } else { + builder.maxPoints(0); + builder.minPoints(pointsValue); + } + return builder.build(); + }; + } + + @Override + public SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ) { + criteria.add( + criterion( + description, + testClassName + (publicTest ? "Public" : "Private"), + testMethodsSignature, + () -> 1 + ) + ); + return this; + } + + @Override + public SubtaskBuilder requirement(String description, Map>> testMethodsSignature) { + requirements.add( + criterion( + description, + testClassName + "Private", + testMethodsSignature, + () -> -criteria.stream() + .map(Supplier::get) + .mapToInt(Gradable::getMaxPoints) + .sum() + ) + ); + return this; + } + + @Override + public Subtask build() { + if (testClassName.isBlank()) { + throw new IllegalStateException("Test class name must be set"); + } + return new Subtask( + description, + criteria.stream().map(Supplier::get).toList(), + requirements.stream().map(Supplier::get).toList() + ); + } + } +} diff --git a/solution/H10/src/graderPublic/java/h10/rubric/Task.java b/solution/H10/src/graderPublic/java/h10/rubric/Task.java new file mode 100644 index 0000000..bd97064 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/rubric/Task.java @@ -0,0 +1,101 @@ +package h10.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a task in a rubric. + * + * @param description a short description of the task + * @param subtasks the subtasks that must be met to complete the task + */ +public record Task(String description, List subtasks) implements Criteriable { + + /** + * Returns a new {@link TaskCriteriaBuilder} to build a {@link Task}. + * + * @return a new task subtasks builder + */ + public static TaskCriteriaBuilder builder() { + return new TaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .addChildCriteria(subtasks.stream().map(Subtask::getCriterion).toArray(Criterion[]::new)) + .build(); + } + + /** + * + */ + public interface TaskCriteriaBuilder extends Builder { + + /** + * Sets the description of the task. + * + * @param description the description of the task + * @return this builder instance with the description set + */ + TaskCriteriaBuilder description(String description); + + /** + * Adds subtasks to the task. + * + * @param subtasks the subtasks to add + * @return this builder instance with the subtasks added + */ + TaskCriteriaBuilder subtasks(Subtask... subtasks); + + /** + * Adds a criterion to the task. + * + * @param criterion the criterion to add + * @return this builder instance with the criterion added + */ + default TaskCriteriaBuilder subtask(Subtask criterion) { + return subtasks(criterion); + } + } + + /** + * A builder for building {@link Task} instances. + */ + private static class TaskCriteriaBuilderImpl implements TaskCriteriaBuilder { + + /** + * The description of the task. + */ + private @NotNull String description = ""; + + /** + * The subtasks of the task. + */ + private final List criteria = new ArrayList<>(); + + @Override + public TaskCriteriaBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public TaskCriteriaBuilder subtasks(Subtask... subtasks) { + this.criteria.addAll(List.of(subtasks)); + return this; + } + + @Override + public Task build() { + if (description.isBlank()) { + throw new IllegalArgumentException("Description cannot be blank"); + } + return new Task(description, criteria); + } + } +} diff --git a/solution/H10/src/graderPublic/java/h10/util/ListItems.java b/solution/H10/src/graderPublic/java/h10/util/ListItems.java new file mode 100644 index 0000000..7e1a5a9 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/util/ListItems.java @@ -0,0 +1,92 @@ +package h10.util; + +import h10.ListItem; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; +import javax.annotation.Nullable; + +/** + * Utility class for working with {@link ListItem}s. + * + * @author Nhan Huynh + */ +public final class ListItems { + + /** + * Prevent instantiation of this utility class. + */ + private ListItems() { + } + + /** + * Returns an {@link Iterator} over the {@link ListItem}s in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return an iterator over the list + */ + public static Iterator> itemIterator(ListItem head) { + return itemStream(head).iterator(); + } + + /** + * Returns an {@link Iterator} over the elements in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return an iterator over the elements in the list + */ + public static Iterator iterator(ListItem head) { + return stream(head).iterator(); + } + + /** + * Returns a {@link Stream} over the {@link ListItem}s in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return a stream over the list + */ + public static Stream> itemStream(ListItem head) { + return Stream.iterate(head, Objects::nonNull, item -> item.next); + } + + /** + * Returns a {@link Stream} over the elements in the list. + * + * @param head the head of the list + * @param the type of the elements in the list + * @return a stream over the elements in the list + */ + public static Stream stream(ListItem head) { + return itemStream(head).map(item -> item.key); + } + + @SafeVarargs + public static ListItem of(T... elements) { + return toItems(List.of(elements)); + } + + /** + * Converts a list of elements to a linked list of {@link ListItem}s. + * + * @param elements the elements to convert + * @param the type of the elements + * @return the head of the list + */ + public static @Nullable ListItem toItems(List elements) { + if (elements.isEmpty()) { + return null; + } + List> items = elements.stream().map(ListItem::new).toList(); + items.stream().reduce((tail, item) -> { + tail.next = item; + item.prev = tail; + return item; + }).orElseThrow(); + return items.getFirst(); + } +} diff --git a/solution/H10/src/graderPublic/java/h10/util/MockList.java b/solution/H10/src/graderPublic/java/h10/util/MockList.java new file mode 100644 index 0000000..9587bc3 --- /dev/null +++ b/solution/H10/src/graderPublic/java/h10/util/MockList.java @@ -0,0 +1,150 @@ +package h10.util; + +import h10.BidirectionalIterator; +import h10.MyList; + +import java.util.ArrayList; +import java.util.ListIterator; + +/** + * A simple implementation of a list that can be used for testing. + * + * @param the type of the elements in the list + */ +public class MockList implements MyList { + + /** + * The delegate list that holds the elements. + */ + private final java.util.List delegate = new ArrayList<>(); + + + /** + * Creates a list with the given elements. + * + * @param elements the elements to add to the list + * @param the type of the elements in the list + * @return the list with the given elements + */ + @SafeVarargs + public static MockList of(T... elements) { + return of(java.util.List.of(elements)); + } + + /** + * Creates a list with the given elements. + * + * @param elements the elements to add to the list + * @param the type of the elements in the list + * @return the list with the given elements + */ + public static MockList of(Iterable elements) { + MockList list = new MockList<>(); + for (T element : elements) { + list.add(element); + } + return list; + } + + @Override + public int findFirst(T key) { + return delegate.indexOf(key); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public T get(int index) { + return delegate.get(index); + } + + @Override + public void add(int index, T key) { + delegate.add(index, key); + } + + @Override + public T removeAtIndex(int index) { + return delegate.remove(index); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public BidirectionalIterator cyclicIterator() { + return new BidirectionalIterator<>() { + + ListIterator it = delegate.listIterator(); + Boolean nextCalled = null; + Boolean removeCalled = false; + + @Override + public boolean hasNext() { + return size() > 0; + } + + private void checkResetNext() { + if (!it.hasNext()) { + it = delegate.listIterator(); + } + } + + private void checkResetPrevious() { + if (!it.hasPrevious()) { + it = delegate.listIterator(size()); + } + } + + @Override + public T next() { + checkResetNext(); + // Case when previous was called + // We need to skip the current element or else we will return the same element + if (nextCalled != null && !nextCalled) { + it.next(); + checkResetNext(); + } + + T next = it.next(); + nextCalled = true; + return next; + } + + @Override + public boolean hasPrevious() { + return size() > 0; + } + + @Override + public T previous() { + checkResetPrevious(); + // Case when next was called + // We need to skip the current element or else we will return the same element + if (nextCalled != null && nextCalled) { + it.previous(); + checkResetPrevious(); + } + T previous = it.previous(); + nextCalled = false; + return previous; + } + + @Override + public void remove() { + it.remove(); + removeCalled = true; + } + }; + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/solution/H10/src/graderPublic/resources/h10/H10_1_1.json b/solution/H10/src/graderPublic/resources/h10/H10_1_1.json new file mode 100644 index 0000000..6b31c72 --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_1_1.json @@ -0,0 +1,37 @@ +[ + { + "names": [ + ] + }, + { + "names": [ + "IU" + ] + }, + { + "names": [ + "Jo Youngmin", + "Jo Kwangmin" + ] + }, + { + "names": [ + "Han", + "Changbin", + "Bang Chan" + ] + }, + { + "names": [ + "Xiumin", + "Suho", + "Lay", + "Baekhyun", + "Chen", + "Chanyeol", + "D.O.", + "Kai", + "Sehun" + ] + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json b/solution/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json new file mode 100644 index 0000000..cc15f0c --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_1_CountSkipCards.json @@ -0,0 +1,234 @@ +[ + { + "deck": [ + "SKIP" + ], + "skips": 1 + }, + { + "deck": [ + "PASS", + "REVERSE" + ], + "skips": 0 + }, + { + "deck": [ + "SKIP", + "PASS", + "DRAW_TWO" + ], + "skips": 1 + }, + { + "deck": [ + "PASS", + "SKIP", + "REVERSE", + "DRAW_TWO", + "PASS" + ], + "skips": 1 + }, + { + "deck": [ + "REVERSE", + "SKIP", + "PASS", + "DRAW_TWO", + "SKIP", + "PASS", + "PASS", + "DRAW_TWO", + "REVERSE", + "SKIP" + ], + "skips": 3 + }, + { + "deck": [ + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP", + "SKIP" + ], + "skips": 10 + }, + { + "deck": [ + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "SKIP", + "PASS", + "DRAW_TWO", + "REVERSE", + "SKIP", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "PASS", + "PASS", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "PASS", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "REVERSE", + "SKIP", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "PASS" + ], + "skips": 9 + }, + { + "deck": [ + "SKIP", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "REVERSE", + "SKIP", + "PASS", + "SKIP", + "PASS", + "DRAW_TWO", + "PASS", + "SKIP", + "PASS", + "DRAW_TWO", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "SKIP", + "REVERSE", + "PASS", + "DRAW_TWO", + "SKIP", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "PASS", + "REVERSE", + "PASS", + "DRAW_TWO", + "PASS", + "PASS", + "PASS", + "SKIP", + "PASS", + "PASS", + "REVERSE", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "REVERSE", + "PASS", + "REVERSE", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "SKIP", + "PASS", + "PASS", + "PASS", + "DRAW_TWO", + "REVERSE", + "PASS", + "SKIP", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "PASS", + "PASS", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "PASS", + "SKIP", + "DRAW_TWO", + "REVERSE", + "SKIP", + "PASS", + "PASS", + "PASS", + "DRAW_TWO", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "PASS", + "REVERSE", + "PASS", + "SKIP", + "DRAW_TWO" + ], + "skips": 23 + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_1.json b/solution/H10/src/graderPublic/resources/h10/H10_2_1.json new file mode 100644 index 0000000..a6c732c --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_1.json @@ -0,0 +1,76 @@ +[ + { + "list": [ + 1 + ], + "key": 1, + "index": 0 + }, + { + "list": [ + 1, + 1, + 1, + 1 + ], + "key": 1, + "index": 0 + }, + { + "list": [ + 5, + 3, + 1, + 7, + 9 + ], + "key": 5, + "index": 0 + }, + { + "list": [ + 5, + 3, + 1, + 7, + 9 + ], + "key": 1, + "index": 2 + }, + { + "list": [ + 5, + 3, + 1, + 7, + 9 + ], + "key": 9, + "index": 4 + }, + { + "list": [ + ], + "key": 1, + "index": -1 + }, + { + "list": [ + -1 + ], + "key": 1, + "index": -1 + }, + { + "list": [ + 2, + 6, + 4, + 8, + 10 + ], + "key": 1, + "index": -1 + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_2_Position.json b/solution/H10/src/graderPublic/resources/h10/H10_2_2_Position.json new file mode 100644 index 0000000..53c26ad --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_2_Position.json @@ -0,0 +1,42 @@ +[ + { + "input": [ + 1 + ], + "index": 0, + "element": 1 + }, + { + "input": [ + 5, + 1, + 3, + 2, + 4 + ], + "index": 0, + "element": 5 + }, + { + "input": [ + 5, + 1, + 3, + 2, + 4 + ], + "index": 2, + "element": 3 + }, + { + "input": [ + 5, + 1, + 3, + 2, + 4 + ], + "index": 4, + "element": 4 + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json b/solution/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json new file mode 100644 index 0000000..87f9c03 --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_3_Exception.json @@ -0,0 +1,92 @@ +[ + { + "input": [ + ], + "index": 1, + "key": 4 + }, + { + "input": [ + ], + "index": -1, + "key": 4 + }, + { + "input": [ + 5, + 22, + 9, + 12, + 15, + 3, + 7, + 8, + 10, + 11, + 13, + 14, + 16, + 17, + 18, + 19, + 20, + 21, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37 + ], + "index": 34, + "key": 4 + }, + { + "input": [ + 5, + 22, + 9, + 12, + 15, + 3, + 7, + 8, + 10, + 11, + 13, + 14, + 16, + 17, + 18, + 19, + 20, + 21, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37 + ], + "index": -43, + "key": 4 + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_3_Start.json b/solution/H10/src/graderPublic/resources/h10/H10_2_3_Start.json new file mode 100644 index 0000000..2c722ac --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_3_Start.json @@ -0,0 +1,50 @@ +[ + { + "input": [ + 25 + ], + "key": 55, + "expected": [ + 55, + 25 + ] + }, + { + "input": [ + 25, + 69 + ], + "key": 55, + "expected": [ + 55, + 25, + 69 + ] + }, + { + "input": [ + 25, + 69, + 12, + 9, + 10, + 23, + 45, + 55, + 26 + ], + "key": 55, + "expected": [ + 55, + 25, + 69, + 12, + 9, + 10, + 23, + 45, + 55, + 26 + ] + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json b/solution/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json new file mode 100644 index 0000000..f32a601 --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_4_Case4.json @@ -0,0 +1,30 @@ +[ + { + "input": [ + 1, + 3, + 5 + ], + "key": 3, + "expected": [ + 1, + 5 + ] + }, + { + "input": [ + 1, + 2, + 3, + 4, + 5 + ], + "key": 3, + "expected": [ + 1, + 2, + 4, + 5 + ] + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_4_References.json b/solution/H10/src/graderPublic/resources/h10/H10_2_4_References.json new file mode 100644 index 0000000..e1f5a34 --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_4_References.json @@ -0,0 +1,26 @@ +[ + { + "input": [ + 11, + 22, + 33 + ], + "key": 11 + }, + { + "input": [ + 11, + 22, + 33 + ], + "key": 22 + }, + { + "input": [ + 11, + 22, + 33 + ], + "key": 33 + } +] diff --git a/solution/H10/src/graderPublic/resources/h10/H10_2_5.json b/solution/H10/src/graderPublic/resources/h10/H10_2_5.json new file mode 100644 index 0000000..e17805c --- /dev/null +++ b/solution/H10/src/graderPublic/resources/h10/H10_2_5.json @@ -0,0 +1,36 @@ +[ + { + "input": [ + 3 + ] + }, + { + "input": [ + 3, + 1 + ] + }, + { + "input": [ + 3, + 1, + 2 + ] + }, + { + "input": [ + 3, + 1, + 1, + 2, + 4, + 6, + 9, + 2, + 1, + 2, + 4, + 7 + ] + } +] diff --git a/solution/H10/src/main b/solution/H10/src/main new file mode 120000 index 0000000..f3448ee --- /dev/null +++ b/solution/H10/src/main @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H10/src/main \ No newline at end of file diff --git a/solution/H10/src/test b/solution/H10/src/test new file mode 120000 index 0000000..8a7072b --- /dev/null +++ b/solution/H10/src/test @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H10/src/test \ No newline at end of file diff --git a/solution/H10/version b/solution/H10/version new file mode 100644 index 0000000..b694fe3 --- /dev/null +++ b/solution/H10/version @@ -0,0 +1 @@ +0.1.0-SNAPSHOT diff --git a/solution/H11/.editorconfig b/solution/H11/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/solution/H11/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/solution/H11/.gitignore b/solution/H11/.gitignore new file mode 100644 index 0000000..1ce268f --- /dev/null +++ b/solution/H11/.gitignore @@ -0,0 +1,86 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +screenshots/ diff --git a/solution/H11/README.md b/solution/H11/README.md new file mode 100644 index 0000000..b8104ce --- /dev/null +++ b/solution/H11/README.md @@ -0,0 +1,4 @@ +# Musterlösung zu Hausübung 11 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/solution/H11/build.gradle.kts b/solution/H11/build.gradle.kts new file mode 100644 index 0000000..c93d7b3 --- /dev/null +++ b/solution/H11/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + alias(libs.plugins.algomate) + alias(libs.plugins.style) +} + +version = file("version").readLines().first() + +exercise { + assignmentId.set("h11") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "ab12cdef" + firstName = "sol_first" + lastName = "sol_last" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h11.H11_RubricProviderPublic") + } + val graderPrivate by creating { + parent(graderPublic) + graderName.set("FOP-2425-H11-Private") + rubricProviderName.set("h11.H11_RubricProviderPrivate") + } + } +} diff --git a/solution/H11/gradle/libs.versions.toml b/solution/H11/gradle/libs.versions.toml new file mode 100644 index 0000000..2a961b5 --- /dev/null +++ b/solution/H11/gradle/libs.versions.toml @@ -0,0 +1,3 @@ +[plugins] +algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } +style = { id = "org.sourcegrade.style", version = "3.0.0" } diff --git a/solution/H11/gradle/wrapper/gradle-wrapper.jar b/solution/H11/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c1962a79e29d3e0ab67b14947c167a862655af9b GIT binary patch literal 62076 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 literal 0 HcmV?d00001 diff --git a/solution/H11/gradle/wrapper/gradle-wrapper.properties b/solution/H11/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..36074ad --- /dev/null +++ b/solution/H11/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/solution/H11/gradlew b/solution/H11/gradlew new file mode 100755 index 0000000..aeb74cb --- /dev/null +++ b/solution/H11/gradlew @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/solution/H11/gradlew.bat b/solution/H11/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/solution/H11/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/solution/H11/settings.gradle.kts b/solution/H11/settings.gradle.kts new file mode 100644 index 0000000..dc07cc0 --- /dev/null +++ b/solution/H11/settings.gradle.kts @@ -0,0 +1,10 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + } +} + +rootProject.name = "H11-Root" diff --git a/solution/H11/src/graderPrivate/java/h11/H11_RubricProvider.java b/solution/H11/src/graderPrivate/java/h11/H11_RubricProvider.java new file mode 100644 index 0000000..b7cc7d4 --- /dev/null +++ b/solution/H11/src/graderPrivate/java/h11/H11_RubricProvider.java @@ -0,0 +1,373 @@ +package h11; + +import org.sourcegrade.jagr.api.rubric.*; + +import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.criterion; + +public class H11_RubricProvider implements RubricProvider { + + // Public test + private static final Criterion H11_1_1 = Criterion.builder() + .shortDescription("H11.1.1 | Lieder länger als ...") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode isLongerThan(int durationInSeconds) von Song gibt true zurück, wenn die Dauer des Songs länger als durationInSeconds ist, sonst false." + ), + criterion( + "Die Methode getSongsLongerThan(int durationInSeconds) von Album gibt alle Songs des Albums zurück, die länger als durationInSeconds sind." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + // Public test + private static final Criterion H11_1_2 = Criterion.builder() + .shortDescription("H11.1.2 | Durchschnittliche Spieldauer eines Albums") + .maxPoints(2) + .addChildCriteria( + criterion( + "Die Methode getAverageDuration() von Album gibt die durchschnittliche Dauer aller Songs des Albums zurück." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -2 + ) + ) + .build(); + + private static final Criterion H11_1 = Criterion.builder() + .shortDescription("H11.1 | Alben") + .addChildCriteria( + H11_1_1, + H11_1_2 + ) + .build(); + + // Public test + private static final Criterion H11_2_1 = Criterion.builder() + .shortDescription("H11.2.1 | Lieder eines Künstlers") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getAllSongs() von Artist gibt eine Liste aller Songs des Künstlers zurück." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + // Public test + private static final Criterion H11_2_2 = Criterion.builder() + .shortDescription("H11.2.2 | Alle Genres eines Künstlers") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getAllGenres() von Artist gibt eine Liste aller Genres der Alben des Künstlers zurück." + ), + criterion( + "Jedes Genre kommt nur einmal in der Liste vor." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + private static final Criterion H11_2 = Criterion.builder() + .shortDescription("H11.2 | Künstler") + .addChildCriteria( + H11_2_1, + H11_2_2 + ) + .build(); + + // Public test + public static final Criterion H11_3_1 = Criterion.builder() + .shortDescription("H11.3.1 | Abgespielte Lieder") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getPlayedSongs() von User gibt eine Liste aller abgespielten Lieder des Benutzers zurück." + ), + criterion( + "Jedes Lied kommt nur einmal in der Liste vor." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + public static final Criterion H11_3_2 = Criterion.builder() + .shortDescription("H11.3.2 | Wie oft wurde ein Lied abgespielt?") + .maxPoints(3) + .addChildCriteria( + criterion( // Public test + "Die Methode getPlayCounts() von User gibt eine Liste aller abgespielten Lieder des Benutzers zurück, zusammen mit der Anzahl der Wiedergaben.", + 2 + ), + criterion( + "Die Liste ist absteigend nach der Anzahl der Wiedergaben sortiert. Bei gleicher Anzahl von Wiedergaben ist die Reihenfolge alphabetisch nach dem Titel des Liedes sortiert." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -3 + ) + ) + .build(); + + public static final Criterion H11_3_3 = Criterion.builder() + .shortDescription("H11.3.3 | Was ist das Lieblingslied?") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getFavoriteSong() von User gibt das am häufigsten abgespielte Lied des Benutzers zurück." + ), + criterion( + "Hat der Benutzer noch kein Lied abgespielt, wird null zurückgegeben." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + public static final Criterion H11_3_4 = Criterion.builder() + .shortDescription("H11.3.4 | Ausgabe der meistgespielten Lieder") + .maxPoints(2) + .addChildCriteria( + criterion( + "Die Methode getTopPlayedSongsList() von User gibt eine Liste von maximal drei Liedern zurück." + ), + criterion( + "Das Format der Ausgabe ist \" ( plays)\" pro Song." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -2 + ) + ) + .build(); + + public static final Criterion H11_3 = Criterion.builder() + .shortDescription("H11.3 | Analysieren von Nutzern") + .addChildCriteria( + H11_3_1, + H11_3_2, + H11_3_3, + H11_3_4 + ) + .build(); + + public static final Criterion H11_4_1 = Criterion.builder() + .shortDescription("H11.4.1 | Alle Lieder") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getAllSongs() von MusicStreaming gibt eine Liste aller Lieder zurück." + ), + criterion( + "Jedes Lied kommt nur einmal in der Liste vor." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + // Public test + public static final Criterion H11_4_2 = Criterion.builder() + .shortDescription("H11.4.2 | Eine neue zufällige Playlist") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode generateRandomPlaylist() von MusicStreaming erstellt einen unendlichen Stream von zufälligen Liedern." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + public static final Criterion H11_4_3 = Criterion.builder() + .shortDescription("H11.4.3 | Nur Lieder bestimmter Länge") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getSongsLongerThan(int durationInSeconds) von MusicStreaming gibt nur Lieder zurück, die länger als durationInSeconds sind." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + public static final Criterion H11_4_4 = Criterion.builder() + .shortDescription("H11.4.4 | Alle Genres") + .maxPoints(1) + .addChildCriteria( + criterion( + "Die Methode getAllGenres() von MusicStreaming gibt eine Liste von in Alben verwendeten Genres zurück." + ), + criterion( + "Jedes Genre kommt nur einmal in der Liste vor." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -1 + ) + ) + .build(); + + public static final Criterion H11_4_5 = Criterion.builder() + .shortDescription("H11.4.5 | Nur Alben eines Genres") + .maxPoints(2) + .addChildCriteria( + criterion( + "Die Methode getAlbumsByGenre() von MusicStreaming gibt eine Map zurück, die jedes Genre auf eine Liste von Alben dieses Genres abbildet.", + 2 + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -2 + ) + ) + .build(); + + public static final Criterion H11_4_6 = Criterion.builder() + .shortDescription("H11.4.6 | Meistgespielte Lieder") + .maxPoints(4) + .addChildCriteria( + criterion( + "Die Methode getGlobalPlayCounts() von MusicStreaming gibt eine Liste aller Lieder und ihrer Gesamtanzahl von Wiedergaben zurück.", + 2 + ), + criterion( + "Die Liste ist absteigend nach der Anzahl der Wiedergaben sortiert. Bei gleicher Anzahl von Wiedergaben ist die Reihenfolge alphabetisch nach dem Titel des Liedes sortiert." + ), + criterion( + "Die Methode getTopPlayedSongsList() von MusicStreaming gibt eine Liste von maximal fünf Liedern zurück." + // Zusammen mit nächstem criterion maximal ein Punkt, Notfalls beide in ein criterion schreiben. + ), + criterion( + "Das Format der Ausgabe ist \" ( plays)\" pro Song." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -4 + ) + ) + .build(); + + public static final Criterion H11_4_7 = Criterion.builder() + .shortDescription("H11.4.7 | Spielzeit eines Künstlers") + .maxPoints(4) + .addChildCriteria( + criterion( // Public test + "Die Methode getArtistPlayTime(Artist artist) von MusicStreaming gibt die Gesamtspielzeit in Sekunden aller Lieder des Künstlers zurück.", + 3 + ), + criterion( + "Die Methode getArtistPlayTimes() von MusicStreaming gibt eine Map zurück, die jeden Künstler auf die Gesamtspielzeit in Sekunden seiner Lieder abbildet.", + 1 + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -4 + ) + ) + .build(); + + public static final Criterion H11_4_8 = Criterion.builder() + .shortDescription("H11.4.8 | Welcher Künstler wurde am meisten gehört?") + .maxPoints(2) + .addChildCriteria( + criterion( // Public test + "Die Methode getMostPlayedArtist() von MusicStreaming gibt den Künstler zurück, dessen Gesamtspielzeit am größten ist." + ), + criterion( + "Hat noch kein Künstler Lieder, wird null zurückgegeben." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -2 + ) + ) + .build(); + + // Public test + public static final Criterion H11_4_9 = Criterion.builder() + .shortDescription("H11.4.9 | Suchen von Liedern") + .maxPoints(2) + .addChildCriteria( + criterion( + "Die Methode searchSongs(Predicate predicate) von MusicStreaming gibt eine Liste von Liedern zurück, die das gegebene Predicate erfüllen.", + 2 + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -2 + ) + ) + .build(); + + public static final Criterion H11_4_10 = Criterion.builder() + .shortDescription("H11.4.10 | Preiserhöhung") + .maxPoints(2) + .addChildCriteria( + criterion( // Public test + "Die Methode adjustPrice(double percentage) von MusicStreaming erhöht oder senkt den Preis für alle Benutzer bei einem postiven bzw. negativen Prozentsatz." + ), + criterion( + "Die Methode adjustPrice(double percentage) von MusicStreaming erhält den Preis für alle Benutzer bei einem Prozentsatz von 0." + ), + criterion( + "Verbindliche Anforderung nicht erfüllt", + -2 + ) + ) + .build(); + + public static final Criterion H11_4 = Criterion.builder() + .shortDescription("H11.4 | Musikstreaming") + .addChildCriteria( + H11_4_1, + H11_4_2, + H11_4_3, + H11_4_4, + H11_4_5, + H11_4_6, + H11_4_7, + H11_4_8, + H11_4_9, + H11_4_10 + ) + .build(); + + public static final Rubric RUBRIC = Rubric.builder() + .title("H11 | Musikstreaming") + .addChildCriteria( + H11_1, + H11_2, + H11_3, + H11_4 + ) + .build(); + + @Override + public Rubric getRubric() { + return RUBRIC; + } +} diff --git a/solution/H11/src/main b/solution/H11/src/main new file mode 120000 index 0000000..0bd7ed0 --- /dev/null +++ b/solution/H11/src/main @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H11/src/main \ No newline at end of file diff --git a/solution/H11/src/test b/solution/H11/src/test new file mode 120000 index 0000000..bcc3216 --- /dev/null +++ b/solution/H11/src/test @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H11/src/test \ No newline at end of file diff --git a/solution/H11/version b/solution/H11/version new file mode 100644 index 0000000..b694fe3 --- /dev/null +++ b/solution/H11/version @@ -0,0 +1 @@ +0.1.0-SNAPSHOT diff --git a/solution/H12/.editorconfig b/solution/H12/.editorconfig new file mode 100644 index 0000000..38866d3 --- /dev/null +++ b/solution/H12/.editorconfig @@ -0,0 +1,12 @@ +# Editor configuration, see https://editorconfig.org + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.yml,*.json}] +indent_size = 2 diff --git a/solution/H12/.gitignore b/solution/H12/.gitignore new file mode 100644 index 0000000..355231b --- /dev/null +++ b/solution/H12/.gitignore @@ -0,0 +1,86 @@ +### Intellij ### +.idea/ +*.iws +/out/ +*.iml +.idea_modules/ +atlassian-ide-plugin.xml + +### VS-Code ### +.vscode/ +.VSCodeCounter/ + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders +.externalToolBuilders/ +*.launch +.factorypath +.recommenders/ +.apt_generated/ +.project +.classpath + +### Linux ### +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* + +### macOS ### +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.lnk + +### Gradle ### +.gradle +/build/ +out/ +gradle-app.setting +!gradle-wrapper.jar +.gradletasknamecache + +*.hprof +*.conf diff --git a/solution/H12/README.md b/solution/H12/README.md new file mode 100644 index 0000000..e59047a --- /dev/null +++ b/solution/H12/README.md @@ -0,0 +1,4 @@ +# Musterlösung zu Hausübung 12 + +Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem +[Studierenden-Guide](https://wiki.tudalgo.org/) diff --git a/solution/H12/build.gradle.kts b/solution/H12/build.gradle.kts new file mode 100644 index 0000000..3d4a3fd --- /dev/null +++ b/solution/H12/build.gradle.kts @@ -0,0 +1,39 @@ +plugins { + alias(libs.plugins.algomate) + alias(libs.plugins.style) +} + +version = file("version").readLines().first() + +exercise { + assignmentId.set("h12") +} + +submission { + // ACHTUNG! + // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen + // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! + // BEISPIEL: + // studentId = "ab12cdef" + // firstName = "sol_first" + // lastName = "sol_last" + studentId = "ab12cdef" + firstName = "sol_first" + lastName = "sol_last" + + // Optionally require own tests for mainBuildSubmission task. Default is false + requireTests = false +} + +jagr { + graders { + val graderPublic by getting { + rubricProviderName.set("h12.H12_RubricProviderPublic") + } + val graderPrivate by creating { + parent(graderPublic) + graderName.set("FOP-2425-H12-Private") + rubricProviderName.set("h12.H12_RubricProviderPrivate") + } + } +} diff --git a/solution/H07/gradle/libs.versions.toml b/solution/H12/gradle/libs.versions.toml similarity index 100% rename from solution/H07/gradle/libs.versions.toml rename to solution/H12/gradle/libs.versions.toml diff --git a/solution/H12/gradle/wrapper/gradle-wrapper.jar b/solution/H12/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c1962a79e29d3e0ab67b14947c167a862655af9b GIT binary patch literal 62076 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 literal 0 HcmV?d00001 diff --git a/solution/H12/gradle/wrapper/gradle-wrapper.properties b/solution/H12/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..36074ad --- /dev/null +++ b/solution/H12/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/solution/H12/gradlew b/solution/H12/gradlew new file mode 100755 index 0000000..aeb74cb --- /dev/null +++ b/solution/H12/gradlew @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/solution/H12/gradlew.bat b/solution/H12/gradlew.bat new file mode 100644 index 0000000..93e3f59 --- /dev/null +++ b/solution/H12/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/solution/H12/settings.gradle.kts b/solution/H12/settings.gradle.kts new file mode 100644 index 0000000..f5be738 --- /dev/null +++ b/solution/H12/settings.gradle.kts @@ -0,0 +1,10 @@ +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { +// mavenLocal() + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + } +} + +rootProject.name = "H12-Root" diff --git a/solution/H12/src/graderPrivate/java/h12/H12_1_2_TestsPrivate.java b/solution/H12/src/graderPrivate/java/h12/H12_1_2_TestsPrivate.java new file mode 100644 index 0000000..88b8585 --- /dev/null +++ b/solution/H12/src/graderPrivate/java/h12/H12_1_2_TestsPrivate.java @@ -0,0 +1,434 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.Links; +import h12.assertions.TestConstants; +import h12.io.BufferedBitOutputStream; +import h12.lang.MyBit; +import h12.lang.MyByte; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for H12.1.2. + * + * @author Nhan Huynh + */ + +@TestForSubmission +@DisplayName("H12.1.2 | Bits schreiben") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_1_2_TestsPrivate extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "bufferPreState", JsonConverters::toMyByte, + "positionPreState", JsonNode::asInt, + "bit", JsonConverters::toBit, + "bitsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "bufferPostState", JsonConverters::toMyByte, + "positionPostState", JsonNode::asInt, + "bitsCalled", node -> JsonConverters.toList(node, JsonNode::asInt) + ); + + /** + * The underlying byte array input stream for the input stream to test. + */ + private @Nullable MockBitOutputStream underlying; + + /** + * The output stream for testing. + */ + private @Nullable BufferedBitOutputStream stream; + + /** + * The field link for the buffer field. + */ + private FieldLink buffer; + + /** + * The field link for the position field. + */ + private FieldLink position; + + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + buffer = Links.getField(getType(), "buffer"); + position = Links.getField(getType(), "position"); + } + + @AfterEach + void tearDown() throws IOException { + if (stream != null) { + stream.close(); + } + } + + @Override + public Class getTestClass() { + return BufferedBitOutputStream.class; + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param preStateBuilder the pre-state builder for the test information + * @param postStateBuilder the post-state builder for the test information + * @param streamGenerator the stream generator for custom stream initialization + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest( + MethodLink method, + Function preStateBuilder, + Function postStateBuilder, + Function streamGenerator, + JsonParameterSet parameters) { + // Test setup + underlying = new MockBitOutputStream(); + stream = streamGenerator.apply(underlying); + + MyByte bufferPreState = parameters.get("bufferPreState"); + buffer.set(stream, bufferPreState); + int positionPreState = parameters.get("positionPreState"); + position.set(stream, positionPreState); + + List bitsPostState = parameters.get("bitsPostState"); + MyByte bufferPostState = parameters.get("bufferPostState"); + int positionPostState = parameters.get("positionPostState"); + + return testInformation(method) + .preState( + preStateBuilder.apply( + TestInformation.builder() + .add("underlying", underlying.getBits().toString()) + .add("buffer", bufferPreState) + .add("position", positionPreState) + ).build() + ) + .postState( + postStateBuilder.apply( + TestInformation.builder() + .add("underlying", bitsPostState) + .add("buffer", bufferPostState) + .add("position", positionPostState) + ).build() + ); + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param preStateBuilder the pre-state builder for the test information + * @param postStateBuilder the post-state builder for the test information + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest( + MethodLink method, + Function preStateBuilder, + Function postStateBuilder, + JsonParameterSet parameters) { + return initTest(method, preStateBuilder, postStateBuilder, BufferedBitOutputStream::new, parameters); + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest(MethodLink method, JsonParameterSet parameters) { + return initTest(method, Function.identity(), Function.identity(), parameters); + } + + /** + * Asserts that the buffer and position are updated correctly after calling the flushBuffer method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + private void assertFlushBufferUpdate(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("flushBuffer"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + method.invoke(stream); + + // Test evaluation + MyByte bufferPostState = parameters.get("bufferPostState"); + int positionPostState = parameters.get("positionPostState"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + assert underlying != null; + Context context = builder.actualState( + TestInformation.builder() + .add("underlying", underlying.getBits().toString()) + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(bufferPostState, bufferActualState, context, comment -> "Buffer is not updated correctly."); + Assertions2.assertEquals(positionPostState, positionActualState, context, + comment -> "Position is not updated correctly."); + } + + @DisplayName("Die Methode flushBuffer() aktualisiert den Puffer und Position korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testFlushBufferUpdateYes.json", customConverters = CUSTOM_CONVERTERS) + void testFlushBufferUpdateYes(JsonParameterSet parameters) throws Throwable { + assertFlushBufferUpdate(parameters); + } + + @DisplayName("Die Methode flushBuffer() aktualisiert nicht den Puffer und Position, wenn nötig.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testFlushBufferUpdateNo.json", customConverters = CUSTOM_CONVERTERS) + void testFlushBufferUpdateNo(JsonParameterSet parameters) throws Throwable { + assertFlushBufferUpdate(parameters); + } + + @DisplayName("Die Methode flushBuffer() schreibt das Zeichen in den internen OutputStream korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testFlushBufferWrite.json", customConverters = CUSTOM_CONVERTERS) + void testFlushBufferWrite(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("flushBuffer"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + method.invoke(stream); + + // Test evaluation + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + assert underlying != null; + Context context = builder.actualState( + TestInformation.builder() + .add("underlying", underlying.getBits().toString()) + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + List bitsPostState = parameters.get("bitsPostState"); + Assertions2.assertEquals(bitsPostState, underlying.getBitsUnflushed(), + context, comment -> "Buffer was written incorrectly"); + } + + /** + * Initializes the test for the writeBit(MyBit) method. + * + * @param parameters the parameters for the test + */ + private TestInformation.TestInformationBuilder initWriteBitTest(JsonParameterSet parameters) { + // Access method to test + return initTest( + getMethod("writeBit", MyBit.class), + builder -> builder.add("bit", parameters.get("bit")), + Function.identity(), + parameters + ); + } + + /** + * Asserts that the buffer is written correctly after calling the writeBit method. + * + * @param parameters the parameters for the test + */ + private void assertWriteBitFlush(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("writeBit", MyBit.class); + + // Test setup + TestInformation.TestInformationBuilder builder = initWriteBitTest(parameters); + MyBit bit = parameters.get("bit"); + + // Test execution + method.invoke(stream, bit); + + // Test evaluation + assert underlying != null; + Context context = builder.actualState( + TestInformation.builder() + .add("underlying", underlying.getBits().toString()) + .add("buffer", buffer.get(stream)) + .add("position", position.get(stream)) + .build() + ).build(); + List bitsPostState = parameters.get("bitsPostState"); + + // Validate output + Assertions2.assertEquals(bitsPostState, underlying.getBitsUnflushed(), context, + comment -> "Buffer was not written correctly."); + } + + @DisplayName("Die Methode writeBit(Bit bit) schreibt das Zeichen in den internen OutputStream, falls der Puffer voll ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testWriteBitFlushYes.json", customConverters = CUSTOM_CONVERTERS) + void testWriteBitFlushYes(JsonParameterSet parameters) throws Throwable { + assertWriteBitFlush(parameters); + } + + @DisplayName("Die Methode writeBit(Bit bit) schreibt das Zeichen in den internen OutputStream, falls der Puffer voll ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testWriteBitFlushNo.json", customConverters = CUSTOM_CONVERTERS) + void testWriteBitFlushNo(JsonParameterSet parameters) throws Throwable { + assertWriteBitFlush(parameters); + } + + @DisplayName("Die Methode writeBit(Bit bit) schreibt ein Bit korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testWriteBit.json", customConverters = CUSTOM_CONVERTERS) + void testWriteBit(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("writeBit", MyBit.class); + + // Test setup + TestInformation.TestInformationBuilder builder = initWriteBitTest(parameters); + MyBit bit = parameters.get("bit"); + + // Test execution + method.invoke(stream, bit); + + // Test evaluation + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + assert underlying != null; + Context context = builder.actualState( + TestInformation.builder() + .add("underlying", bufferActualState) + .add("buffer", buffer.get(stream)) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(parameters.get("positionPostState"), positionActualState, + context, comment -> "Position was not updated correctly."); + Assertions2.assertEquals(parameters.get("bufferPostState"), bufferActualState, + context, comment -> "Buffer was not updated correctly."); + } + + /** + * Initializes the test for the write(int) method. + * + * @param streamGenerator the stream generator for custom stream initialization + * @param parameters the parameters for the test + */ + private TestInformation.TestInformationBuilder initWriteTest( + Function streamGenerator, + JsonParameterSet parameters + ) { + // Access method to test + return initTest( + getMethod("writeBit", MyBit.class), + builder -> builder.add("byte", parameters.get("byte")), + Function.identity(), + streamGenerator, + parameters + ); + } + + @DisplayName("Die Methode write(int b) schreibt ein Byte korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testWrite.json", customConverters = CUSTOM_CONVERTERS) + void testWrite(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("write", int.class); + + // Test setup + List bits = new ArrayList<>(); + TestInformation.TestInformationBuilder builder = initWriteTest( + generator -> new BufferedBitOutputStream(generator) { + @Override + public void writeBit(MyBit bit) throws IOException { + bits.add(bit.intValue()); + } + }, + parameters + ); + int byteValue = parameters.getInt("byte"); + + // Test execution + method.invoke(stream, byteValue); + + // Test evaluation + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + assert underlying != null; + Context context = builder.actualState( + TestInformation.builder() + .add("Bits written", bits) + .build() + ).build(); + + List bitsCalled = parameters.get("bitsCalled"); + + Assertions2.assertEquals(bitsCalled, bits, + context, comment -> "Buffer was not written correctly."); + } + + @DisplayName("Die Methode write(int b) wirft eine IllegalArgumentException, falls die Eingabe kein Byte ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_2_testWriteIllegalArgumentException.json", customConverters = CUSTOM_CONVERTERS) + void testWriteIllegalArgumentException(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("write", int.class); + + // Test setup + TestInformation.TestInformationBuilder builder = initWriteTest(BufferedBitOutputStream::new, parameters); + int byteValue = parameters.getInt("byte"); + + // Test execution and evaluation + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + assert underlying != null; + Context context = builder.actualState( + TestInformation.builder() + .add("underlying", bufferActualState) + .add("buffer", buffer.get(stream)) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertThrows(IllegalArgumentException.class, () -> method.invoke(stream, byteValue), + context, comment -> "IllegalArgumentException was not thrown."); + } +} diff --git a/solution/H12/src/graderPrivate/java/h12/H12_2_2_TestsPrivate.java b/solution/H12/src/graderPrivate/java/h12/H12_2_2_TestsPrivate.java new file mode 100644 index 0000000..9a0bd3b --- /dev/null +++ b/solution/H12/src/graderPrivate/java/h12/H12_2_2_TestsPrivate.java @@ -0,0 +1,241 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.rle.BitRunningLengthDecompressor; +import h12.lang.MyBit; +import h12.mock.MockBitInputStream; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for H12.2.2. + * + * @author Nhan Huynh + */ + +@TestForSubmission +@DisplayName("H12.2.2 | BitRunningLengthDecompressor") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_2_2_TestsPrivate extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "inPreState", JsonConverters::toBitInputStream, + "count", JsonNode::asInt, + "bit", JsonConverters::toBit, + "inPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "outPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "counts", node -> JsonConverters.toList(node, JsonNode::asInt), + "bits", node -> JsonConverters.toList(node, JsonConverters::toBit) + ); + + /** + * The input stream to decompress from. + */ + private @Nullable MockBitInputStream in; + + /** + * The output stream to write to. + */ + private @Nullable MockBitOutputStream out; + + /** + * The decompressor to test. + */ + private @Nullable BitRunningLengthDecompressor decompressor; + + @AfterEach + void tearDown() throws Exception { + if (decompressor != null) { + decompressor.close(); + } + } + + @Override + public Class getTestClass() { + return BitRunningLengthDecompressor.class; + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param preStateBuilder the pre-state builder for the test information + * @param postStateBuilder the post-state builder for the test information + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest( + MethodLink method, + Function preStateBuilder, + Function postStateBuilder, + JsonParameterSet parameters) { + // Test setup + in = parameters.get("inPreState"); + out = new MockBitOutputStream(); + assert in != null; + decompressor = new BitRunningLengthDecompressor(in, out); + + List inPostState = parameters.get("inPostState"); + List outPostState = parameters.get("outPostState"); + + return testInformation(method).preState( + preStateBuilder.apply(TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + ).build() + ).postState( + postStateBuilder.apply(TestInformation.builder() + .add("in", inPostState.toString()) + .add("out", outPostState.toString()) + ).build() + ); + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest(MethodLink method, JsonParameterSet parameters) { + return initTest(method, Function.identity(), Function.identity(), parameters); + } + + @DisplayName("Die Methode writeBit(int count, Bit bit) schreibt die Anzahl an aufeinanderfolgenden wiederholenden Bits korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_2_2_testWriteBit.json", customConverters = CUSTOM_CONVERTERS) + void testWriteBit(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("writeBit", int.class, MyBit.class); + + // Test setup + int count = parameters.getInt("count"); + MyBit bit = parameters.get("bit"); + TestInformation.TestInformationBuilder builder = initTest( + method, + preState -> preState.add("count", count).add("bit", bit), + Function.identity(), + parameters + ); + + // Test execution + method.invoke(decompressor, count, bit); + + // Close it to flush the output + assert decompressor != null; + decompressor.close(); + + // Test evaluation + assert in != null; + assert out != null; + List outPostState = parameters.get("outPostState"); + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ).build(); + + Assertions2.assertEquals(outPostState, out.getBits(), context, + comment -> "Wrong bits written to the output stream."); + } + + @DisplayName("Die Methode decompress() liest die Anzahl an aufeinanderfolgenden wiederholenden Bits.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_2_2_testDecompressBitCount.json", customConverters = CUSTOM_CONVERTERS) + void testDecompressBitCount(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("decompress"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest( + method, + preState -> preState.add("out", "Not tracked"), + postState -> postState.add("out", "Not tracked"), + parameters + ); + + // Test execution and evaluation + assert in != null; + assert out != null; + List counts = parameters.get("counts"); + List bits = parameters.get("bits"); + assert decompressor != null; + decompressor.close(); + decompressor = new BitRunningLengthDecompressor(in, out) { + int i = 0; + + @Override + protected void writeBit(int count, MyBit bit) throws IOException { + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits()) + .add("out", "Not tracked") + .build() + ).build(); + int expectedCount = counts.get(i); + MyBit expectedBit = bits.get(i); + Assertions2.assertEquals(expectedCount, count, context, + comment -> "Wrong count written to the output stream."); + Assertions2.assertEquals(expectedBit, bit, context, + comment -> "Wrong bit written to the output stream."); + i++; + } + }; + method.invoke(decompressor); + } + + @DisplayName("Die Methode decompress() dekomprimiert korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_2_2_testDecompress.json", customConverters = CUSTOM_CONVERTERS) + void testDecompress(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("decompress"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + method.invoke(decompressor); + + // Test evaluation + assert in != null; + assert out != null; + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits()) + .add("out", out.getBits()) + .build() + ).build(); + List outPostState = parameters.get("outPostState"); + + Assertions2.assertTrue(out.isFlushed(), context, + comment -> "The output stream is not flushed."); + Assertions2.assertEquals(outPostState, out.getBits(), context, + comment -> "Wrong bits written to the output stream."); + } +} diff --git a/solution/H12/src/graderPrivate/java/h12/H12_3_1_TestsPrivate.java b/solution/H12/src/graderPrivate/java/h12/H12_3_1_TestsPrivate.java new file mode 100644 index 0000000..60f7948 --- /dev/null +++ b/solution/H12/src/graderPrivate/java/h12/H12_3_1_TestsPrivate.java @@ -0,0 +1,116 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.huffman.HuffmanCoding; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +/** + * Defines the private tests for H12.3.1. + * + * @author Nhan Huynh + */ + +@TestForSubmission +@DisplayName("H12.3.1 | Häufigkeitstabelle") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_3_1_TestsPrivate extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "text", JsonNode::asText, + "frequency", node -> JsonConverters.toMap(node, key -> key.charAt(0), JsonNode::asInt) + ); + + + @Override + public Class getTestClass() { + return HuffmanCoding.class; + } + + private TestInformation.TestInformationBuilder initTest(JsonParameterSet parameters) { + // Access method to test + MethodLink method = getMethod("buildFrequencyTable", String.class); + + // Test setup + String text = parameters.get("text"); + + return testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .build() + ); + } + + @DisplayName("Die Methode buildFrequencyTable(String text) erstellt die Häufigkeitstabelle mit allen Zeichen als Schlüssel korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_3_1_testBuildFrequencyTable.json", customConverters = CUSTOM_CONVERTERS) + void testBuildFrequencyTableKeys(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("buildFrequencyTable", String.class); + + // Test setup + String text = parameters.get("text"); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .build() + ); + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + Map actualFrequency = method.invoke(coding, text); + + // Test evaluation + Map frequency = parameters.get("frequency"); + Set keys = frequency.keySet(); + + Context context = builder.build(); + Assertions2.assertEquals(keys, actualFrequency.keySet(), context, + comment -> "The keys of the built frequency table are not correct."); + } + + @DisplayName("Die Methode buildFrequencyTable(String text) erstellt die Häufigkeitstabelle mt den Häufigkeiten korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_3_1_testBuildFrequencyTable.json", customConverters = CUSTOM_CONVERTERS) + void testResult(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("buildFrequencyTable", String.class); + + // Test setup + String text = parameters.get("text"); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .build() + ); + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + Map actualFrequency = method.invoke(coding, text); + + // Test evaluation + Map frequency = parameters.get("frequency"); + Context context = builder.build(); + Assertions2.assertEquals(frequency, actualFrequency, context, + comment -> "The built frequency table is not correct."); + } +} diff --git a/solution/H12/src/graderPrivate/java/h12/H12_3_2_TestsPrivate.java b/solution/H12/src/graderPrivate/java/h12/H12_3_2_TestsPrivate.java new file mode 100644 index 0000000..89d59c9 --- /dev/null +++ b/solution/H12/src/graderPrivate/java/h12/H12_3_2_TestsPrivate.java @@ -0,0 +1,57 @@ +package h12; + +import h12.assertions.TestConstants; +import h12.io.compress.huffman.HuffmanCoding; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.Comparator; +import java.util.Map; +import java.util.function.BiFunction; + +/** + * Defines the private tests for H12.3.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.3.2 | Huffman-Baum") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_3_2_TestsPrivate extends H12_3_2_TestsPublic { + + @DisplayName("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) ist vollständig und korrekt.") + @Test + void testResult() throws Throwable { + // Access method to test + MethodLink method = getMethod("build", Map.class, BiFunction.class, BiFunction.class, Comparator.class); + + // Test setup + Map frequency = Map.of('a', 1, 'b', 2, 'c', 3, 'd', 4); + BiFunction> f = Map::entry; + BiFunction, Map.Entry, Map.Entry> g = + (e1, e2) -> Map.entry(e1.getKey(), e1.getValue() + e2.getValue()); + Comparator> cmp = Comparator.comparingInt(Map.Entry::getValue); + + // Context information + Context context = testInformation(method) + .add("frequency", frequency) + .add("f", "(Character, Integer) -> Map.Entry") + .add("g", "(Map.Entry, Map.Entry) -> Map.Entry") + .add("cmp", "Integer <= Integer") + .build(); + + // Test method + HuffmanCoding coding = new HuffmanCoding(); + Map.Entry actual = method.invoke(coding, frequency, f, g, cmp); + Map.Entry expected = Map.entry('d', 10); + + Assertions2.assertEquals(expected, actual, context, comment -> "The computed result is not correct."); + } +} diff --git a/solution/H12/src/graderPrivate/java/h12/H12_4_2_TestsPrivate.java b/solution/H12/src/graderPrivate/java/h12/H12_4_2_TestsPrivate.java new file mode 100644 index 0000000..c08cd8d --- /dev/null +++ b/solution/H12/src/graderPrivate/java/h12/H12_4_2_TestsPrivate.java @@ -0,0 +1,268 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.EncodingTable; +import h12.io.compress.huffman.HuffmanCodingDecompressor; +import h12.lang.MyByte; +import h12.mock.MockBitInputStream; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the private tests for H12.4.2. + * + * @author Nhan Huynh + */ + +@TestForSubmission +@DisplayName("H12.4.2 | Huffman-Dekomprimierung") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_4_2_TestsPrivate extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "inPreState", JsonConverters::toBitInputStream, + "encodingTable", JsonConverters::toEncodingTable, + "inPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "outPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "skipBits", JsonNode::asInt, + "character", node -> node.asText().charAt(0), + "text", JsonNode::asText + ); + + /** + * The input stream used for testing. + */ + private @Nullable MockBitInputStream in; + + /** + * The output stream used for testing. + */ + private @Nullable MockBitOutputStream out; + + /** + * The decompressor to test. + */ + private @Nullable HuffmanCodingDecompressor decompressor; + + @AfterEach + void tearDown() throws Exception { + if (decompressor != null) { + decompressor.close(); + } + } + + @Override + public Class getTestClass() { + return HuffmanCodingDecompressor.class; + } + + @DisplayName("Die Methode skipBits() überspringt die Füllbits korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_2_testSkipBits.json", customConverters = CUSTOM_CONVERTERS) + void testSkipBits(JsonParameterSet parameters) throws Throwable { + // Access the method + MethodLink method = getMethod("skipBits"); + + // Test setup + in = parameters.get("inPreState"); + out = new MockBitOutputStream(); + decompressor = new HuffmanCodingDecompressor(in, out); + + assert in != null; + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ) + .postState( + TestInformation.builder() + .add("in", parameters.get("inPostState")) + .add("out", parameters.get("outPostState")) + .build() + ); + + // Test execution + method.invoke(decompressor); + + // Close it to flush the output + decompressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ).build(); + int skipBits = parameters.get("skipBits"); + int actualSkipBits = in.getBits().size() - in.getRemainingBits().size() - MyByte.NUMBER_OF_BITS; + Assertions2.assertEquals(skipBits, actualSkipBits, context, + comment -> "Wrong number of bits skipped." + ); + Assertions2.assertEquals(0, out.getBits().size(), context, + comment -> "The output stream should be empty when skipping the bits." + ); + } + + + @DisplayName("Die Methode decodeCharacter(int startBit, EncodingTable encodingTable) dekomprimiert einen Zeichen korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_2_testDecodeCharacter.json", customConverters = CUSTOM_CONVERTERS) + void testDecodeCharacter(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("decodeCharacter", int.class, EncodingTable.class); + + // Test setup + in = parameters.get("inPreState"); + out = new MockBitOutputStream(); + decompressor = new HuffmanCodingDecompressor(in, out); + int startBit = parameters.get("startBit"); + EncodingTable encodingTable = parameters.get("encodingTable"); + + assert in != null; + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .add("startBit", startBit) + .add("encodingTable", encodingTable) + .build() + ).postState( + TestInformation.builder() + .add("in", parameters.get("inPostState")) + .add("out", parameters.get("outPostState")) + .build() + ); + + // Test execution + char actual = method.invoke(decompressor, startBit, encodingTable); + // Close it to flush the output + decompressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ).build(); + + char expected = parameters.get("character"); + Assertions2.assertEquals(expected, actual, context, + comment -> "The decoded character is incorrect." + ); + } + + @DisplayName("Die Methode decodeText(EncodingTable encodingTable) dekomprimiert den Text korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_2_testDecodeText.json", customConverters = CUSTOM_CONVERTERS) + void testDecodeText(JsonParameterSet parameters) throws Throwable { + // Access the method + MethodLink method = getMethod("decodeText", EncodingTable.class); + + // Test setup + in = parameters.get("inPreState"); + out = new MockBitOutputStream(); + decompressor = new HuffmanCodingDecompressor(in, out); + EncodingTable encodingTable = parameters.get("encodingTable"); + + assert in != null; + List outPostState = parameters.get("outPostState"); + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .add("encodingTable", encodingTable) + .build() + ).postState( + TestInformation.builder() + .add("in", parameters.get("inPostState")) + .add("out", outPostState) + .build() + ); + + // Test execution + method.invoke(decompressor, encodingTable); + + // Close it to flush the output + decompressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ).build(); + + Assertions2.assertEquals(outPostState, out.getBits(), context, + comment -> "The decoded text is incorrect correct." + ); + } + + @DisplayName("Die Methode decompress() ist vollständig und korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_2_testDecompress.json", customConverters = CUSTOM_CONVERTERS) + void testDecompress(JsonParameterSet parameters) throws Throwable { + // // Access method to test + MethodLink method = getMethod("decompress"); + + // Test setup + MockBitInputStream in = parameters.get("inPreState"); + MockBitOutputStream out = new MockBitOutputStream(); + decompressor = new HuffmanCodingDecompressor(in, out); + List outPostState = parameters.get("outPostState"); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ).postState( + TestInformation.builder() + .add("in", parameters.get("inPostState")) + .add("out", outPostState) + .add("out (String)", parameters.get("text")) + .build() + ); + + // Test execution + method.invoke(decompressor); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getBits().toString()) + .add("out", out.getBits().toString()) + .build() + ).build(); + Assertions2.assertTrue(out.isFlushed(), context, + comment -> "The output stream is not flushed."); + Assertions2.assertEquals(outPostState, out.getBits(), context, + comment -> "The decoded text is incorrect." + ); + } +} diff --git a/solution/H12/src/graderPrivate/java/h12/H12_RubricProviderPrivate.java b/solution/H12/src/graderPrivate/java/h12/H12_RubricProviderPrivate.java new file mode 100644 index 0000000..4785547 --- /dev/null +++ b/solution/H12/src/graderPrivate/java/h12/H12_RubricProviderPrivate.java @@ -0,0 +1,18 @@ +package h12; + +import h12.rubric.H12_RubricProvider; + +/** + * A private rubric provider for H12. + * + * @author Nhan Huynh + */ +public class H12_RubricProviderPrivate extends H12_RubricProvider { + + /** + * Constructs a new public rubric provider. + */ + public H12_RubricProviderPrivate() { + super(false); + } +} diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateNo.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateNo.json new file mode 100644 index 0000000..dac01f9 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateNo.json @@ -0,0 +1,9 @@ +[ + { + "bufferPreState": 20, + "positionPreState": 7, + "bufferPostState": 20, + "positionPostState": 7, + "bitsPostState": [] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateYes.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateYes.json new file mode 100644 index 0000000..66de0ab --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferUpdateYes.json @@ -0,0 +1,50 @@ +[ + { + "bufferPreState": 20, + "positionPreState": 0, + "bufferPostState": 0, + "positionPostState": 7, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0 + ] + }, + { + "bufferPreState": 20, + "positionPreState": 4, + "bufferPostState": 0, + "positionPostState": 7, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0 + ] + }, + { + "bufferPreState": 20, + "positionPreState": 6, + "bufferPostState": 0, + "positionPostState": 7, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferWrite.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferWrite.json new file mode 100644 index 0000000..d1583b9 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testFlushBufferWrite.json @@ -0,0 +1,18 @@ +[ + { + "bufferPreState": 20, + "positionPreState": 4, + "bufferPostState": 0, + "positionPostState": 7, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWrite.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWrite.json new file mode 100644 index 0000000..122e48e --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWrite.json @@ -0,0 +1,102 @@ +[ + { + "positionPreState": 7, + "bufferPreState": 0, + "byte": 69, + "positionPostState": -1, + "bufferPostState": 69, + "bitsPostState": [ + ], + "bitsCalled": [ + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1 + ] + }, + { + "positionPreState": 4, + "bufferPreState": 160, + "byte": 69, + "positionPostState": 4, + "bufferPostState": 160, + "bitsPostState": [ + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0 + ], + "bitsCalled": [ + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1 + ] + }, + { + "positionPreState": 0, + "bufferPreState": 170, + "byte": 69, + "positionPostState": 0, + "bufferPostState": 138, + "bitsPostState": [ + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0 + ], + "bitsCalled": [ + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1 + ] + }, + { + "positionPreState": -1, + "bufferPreState": 171, + "byte": 69, + "positionPostState": -1, + "bufferPostState": 69, + "bitsPostState": [ + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1 + ], + "bitsCalled": [ + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBit.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBit.json new file mode 100644 index 0000000..27feb48 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBit.json @@ -0,0 +1,66 @@ +[ + { + "positionPreState": 7, + "bufferPreState": 0, + "bit": 0, + "positionPostState": 6, + "bufferPostState": 0, + "bitsPostState": [] + }, + { + "positionPreState": 7, + "bufferPreState": 0, + "bit": 1, + "positionPostState": 6, + "bufferPostState": 128, + "bitsPostState": [] + }, + { + "positionPreState": 4, + "bufferPreState": 0, + "bit": 0, + "positionPostState": 3, + "bufferPostState": 0, + "bitsPostState": [] + }, + { + "positionPreState": 4, + "bufferPreState": 0, + "bit": 1, + "positionPostState": 3, + "bufferPostState": 16, + "bitsPostState": [] + }, + { + "positionPreState": 4, + "bufferPreState": 160, + "bit": 0, + "positionPostState": 3, + "bufferPostState": 160, + "bitsPostState": [] + }, + { + "positionPreState": 4, + "bufferPreState": 160, + "bit": 1, + "positionPostState": 3, + "bufferPostState": 176, + "bitsPostState": [] + }, + { + "positionPreState": 0, + "bufferPreState": 180, + "bit": 0, + "positionPostState": -1, + "bufferPostState": 180, + "bitsPostState": [] + }, + { + "positionPreState": 0, + "bufferPreState": 180, + "bit": 1, + "positionPostState": -1, + "bufferPostState": 181, + "bitsPostState": [] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushNo.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushNo.json new file mode 100644 index 0000000..ae85998 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushNo.json @@ -0,0 +1,26 @@ +[ + { + "bufferPreState": 20, + "positionPreState": 0, + "bit": 1, + "bufferPostState": 20, + "positionPostState": -1, + "bitsPostState": [] + }, + { + "bufferPreState": 20, + "positionPreState": 4, + "bit": 1, + "bufferPostState": 20, + "positionPostState": 3, + "bitsPostState": [] + }, + { + "bufferPreState": 20, + "positionPreState": 6, + "bit": 1, + "bufferPostState": 20, + "positionPostState": 5, + "bitsPostState": [] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushYes.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushYes.json new file mode 100644 index 0000000..6a6a560 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteBitFlushYes.json @@ -0,0 +1,19 @@ +[ + { + "bufferPreState": 20, + "positionPreState": -1, + "bit": 1, + "bufferPostState": 0, + "positionPostState": 7, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteIllegalArgumentException.json b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteIllegalArgumentException.json new file mode 100644 index 0000000..1c87535 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_1_2_testWriteIllegalArgumentException.json @@ -0,0 +1,26 @@ +[ + { + "positionPreState": 7, + "bufferPreState": 0, + "byte": -1, + "positionPostState": 7, + "bufferPostState": 0, + "bitsPostState": [] + }, + { + "positionPreState": 7, + "bufferPreState": 0, + "byte": 257, + "positionPostState": 7, + "bufferPostState": 0, + "bitsPostState": [] + }, + { + "positionPreState": 7, + "bufferPreState": 0, + "byte": 421421, + "positionPostState": 7, + "bufferPostState": 0, + "bitsPostState": [] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompress.json b/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompress.json new file mode 100644 index 0000000..bb6ab88 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompress.json @@ -0,0 +1,876 @@ +[ + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ], + "inPostState": [ + ], + "outPostState": [ + 0 + ] + }, + { + "inPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "inPostState": [ + ], + "outPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ] + }, + { + "inPreState": [ + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0 + ], + "inPostState": [ + ], + "outPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + }, + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0 + ], + "inPostState": [ + ], + "outPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompressBitCount.json b/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompressBitCount.json new file mode 100644 index 0000000..40821fc --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testDecompressBitCount.json @@ -0,0 +1,68 @@ +[ + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ], + "counts": [ + 1 + ], + "bits": [ + 0 + ], + "inPostState": [ + ], + "outPostState": [ + ] + }, + { + "inPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "counts": [ + 127 + ], + "bits": [ + 1 + ], + "inPostState": [ + ], + "outPostState": [ + ] + }, + { + "inPreState": [ + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0 + ], + "counts": [ + 42 + ], + "bits": [ + 0 + ], + "inPostState": [ + ], + "outPostState": [ + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testWriteBit.json b/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testWriteBit.json new file mode 100644 index 0000000..9047d84 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_2_2_testWriteBit.json @@ -0,0 +1,82 @@ +[ + { + "inPreState": [ + 1 + ], + "count": 1, + "bit": 1, + "inPostState": [ + ], + "outPostState": [ + 1 + ] + }, + { + "inPreState": [ + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0 + ], + "count": 5, + "bit": 1, + "inPostState": [ + ], + "outPostState": [ + 1, + 1, + 1, + 1, + 1 + ] + }, + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0 + ], + "count": 11, + "bit": 0, + "inPostState": [ + ], + "outPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_3_1_testBuildFrequencyTable.json b/solution/H12/src/graderPrivate/resources/h12/H12_3_1_testBuildFrequencyTable.json new file mode 100644 index 0000000..17be360 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_3_1_testBuildFrequencyTable.json @@ -0,0 +1,49 @@ +[ + { + "text": "H", + "frequency": { + "H": 1 + } + }, + { + "text": "HHHHHHHHHHHHHHHHHH ", + "frequency": { + "H": 18, + " ": 1 + } + }, + { + "text": "The quick brown fox jumps over the lazy dog.", + "frequency": { + "T": 1, + " ": 8, + "a": 1, + "b": 1, + "c": 1, + "d": 1, + "e": 3, + "f": 1, + "g": 1, + "h": 2, + "i": 1, + "j": 1, + "k": 1, + "l": 1, + "m": 1, + ".": 1, + "n": 1, + "o": 4, + "p": 1, + "q": 1, + "r": 2, + "s": 1, + "t": 1, + "u": 2, + "v": 1, + "w": 1, + "x": 1, + "y": 1, + "z": 1 + } + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeCharacter.json b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeCharacter.json new file mode 100644 index 0000000..bd47541 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeCharacter.json @@ -0,0 +1,256 @@ +[ + { + "startBit": 1, + "inPreState": [ + 0, + 0 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "H", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 0, + "inPreState": [ + 0, + 0 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "e", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 0, + "inPreState": [ + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "l", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 0, + 0 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "H", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 0, + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "o", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 1, + 0, + 0 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": " ", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 0, + "inPreState": [ + 0, + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "W", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 0, + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "o", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 1, + 1, + 0 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "r", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 0, + "inPreState": [ + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "l", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 1, + 1, + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "d", + "inPostState": [], + "outPostState": [] + }, + { + "startBit": 1, + "inPreState": [ + 1, + 0, + 1 + ], + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "character": "!", + "inPostState": [], + "outPostState": [] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeText.json b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeText.json new file mode 100644 index 0000000..d87ff52 --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecodeText.json @@ -0,0 +1,43479 @@ +[ + { + "inPreState": [ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1 + ], + "text": "Hello World!", + "encodingTable": { + " ": "1100", + "!": "1101", + "r": "1110", + "d": "1111", + "e": "000", + "W": "001", + "H": "100", + "l": "01", + "o": "101" + }, + "inPostState": [ + ], + "outPostState": [ + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "inPreState": [ + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ], + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw inPreState draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by inPreState music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity inPreState dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as inPreState understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration inPreState particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no inPreState. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched inPreState on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "inPostState": [ + ], + "outPostState": [ + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0 + ] + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecompress.json b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecompress.json new file mode 100644 index 0000000..5d7467b --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testDecompress.json @@ -0,0 +1,86885 @@ +[ + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1 + ], + "inPostState": [ + ], + "outPostState": [ + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1 + ], + "text": "Hello, World!" + }, + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ], + "inPostState": [ + ], + "outPostState": [ + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0 + ], + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw inPreState draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by inPreState music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity inPreState dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as inPreState understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration inPreState particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no inPreState. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched inPreState on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh." + }, + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "inPostState": [ + ], + "outPostState": [ + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0 + ], + "text": "Habs bi dies en satz. Oha was gefallt woruber erzahlt das stellte steigst tat glatten. Ige der kraftiger schneider plaudernd vom schonsten. Es du kenne vater stuck. Namlich abwarts gut mundart gab tur nur. Viele du immer szene leise kaute so.\n\nGar meisterin ihn arbeitete uhr ernsthaft. Im bewirtung da gestorben du zerfasert verodeten. Frohlich ist schuftet hinabsah begierig gar dus ihr. Stimmts weg gedacht glatten zum weibern ort ist. Hande sehet kennt te da lauft. Ichs inPreState welt pa eile hing. Ei betrubte da wo geworden launisch ehrbaren madchens.\n\nZu ku auskleiden aufzulosen dazwischen. Lockere ich grausam mundart hochmut ein fenster. Du aufraumen lieblinge geblendet vergesset zu. Mit bettstatt gib schneider hemdarmel unterwegs war. Sog klein das sagen kalte leise vom zwirn licht. Hellen verlie uhr kommen jungen bis freute eck schade gut. Samstag konnten gefreut nun zuliebe vor lichten.\n\nBat ist landsleute hin nachmittag vorpfeifen. Pa es klopfte an flecken wu tadelte. Darauf dus neckte hin als gebaut lag. Kindliche weiterhin mannsbild ob zu windstill. Herr gast sei gut ists. Hufschmied bat ehe wei scherzwort drechslers grundstuck wohlgefuhl man aufgespart. Gehe se luke ruth weil en ei wege. Schen kennt nobel sie gut wie und schau dafur.\n\nSo zaunpfahle mi neidgefuhl em vertreiben wo gesprachig angenommen. Du em paar muhe inPreState so doch. inPreState es frauen te kunste kurios zu. Ist denen leise weich nacht aller eia man steht ich. Losen es ewige zu nicht leben. Hinabsah leichter tadellos mehrmals im ziemlich la em wo.\n\nSa gelernte he am uberging verwohnt. Liebhaben mudigkeit gestrigen nie kam wie tanzmusik ausdenken. An wo du gerbers gelehnt so schritt. Musset mochte du gesund es la sprach seinen. Ubel all tat gelt eine sie tor lied. Verschwand hoffnungen todesfalle er ri an da nettigkeit. Geworden inPreState schonste familien launigen nirgends mi.\n\nIhr grasgarten aus gab ich vorpfeifen nettigkeit bodenlosen. Es ziegen jawohl freude bi fraget bugeln. Em tage te bett arme. Er heran ab so hinab damit rasch. Luften verlie zopfen dir nur. Warf geh alle beim frau den. So heiraten zu konntest fraulein schweren la. Dem beneidest tanzmusik ehe ausdenken gegriffen kraftiger arbeitete gro. Hufschmied verbergend em am sa aufzulosen. Redete luftig klaren fur nur strich stimme ers nur.\n\nVor zog was will ehre paar des. Meinung gelernt scheint flo gefreut manchen das. Es lehrlingen da inPreState nachtessen geschwatzt erhaltenen sonderling schuchtern. Nirgends mi gespielt zugvogel weiblein er em. Ja werkstatte an bescheiden hufschmied neidgefuhl. Ei handwerke en ernstlich kammertur barbieren.\n\nPa wohnstube er kindliche ri schonheit da. Befangenen ihr fluchtigen die lag dachkammer mit. Funfe an schlo enden ja dabei zu es licht. Nichtstun nachgehen im wo lohgruben. Vom ausdenken ist hei filzhutes leuchtete hochstens. Um gern hing so laut da hast.\n\nGesehen konnten inPreState wu dunklem schaute. Einige je wo en inPreState groben besann spater verlor. Schuchtern geheiratet inPreState verrichtet pa bodenlosen betrachtet se am vorpfeifen. Kleine grunde ja da luften werden reihen. Ahren alten enden wo sunde inPreState immer du. Wahrend wie ein nur bereits gewogen niemand man. Froh du voll hing im kerl inPreState euch funf zu. Gebogene ort brauchte uberlegt gut." + } +] diff --git a/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testSkipBits.json b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testSkipBits.json new file mode 100644 index 0000000..407422a --- /dev/null +++ b/solution/H12/src/graderPrivate/resources/h12/H12_4_2_testSkipBits.json @@ -0,0 +1,32997 @@ +[ + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1 + ], + "inPostState": [ + ], + "outPostState": [ + ], + "skipBits": 3 + }, + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ], + "skipBits": 0, + "inPostState": [ + ], + "outPostState": [ + ] + }, + { + "inPreState": [ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "inPostState": [ + ], + "outPostState": [ + ], + "skipBits": 6 + } +] diff --git a/solution/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java b/solution/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java new file mode 100644 index 0000000..8b42d02 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/H12_1_1_TestsPublic.java @@ -0,0 +1,305 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.Links; +import h12.assertions.TestConstants; +import h12.io.BufferedBitInputStream; +import h12.lang.MyByte; +import h12.mock.MockBitInputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +/** + * Defines the public tests for H12.1.1. + * + * @author Nhan Huynh + */ + +@TestForSubmission +@DisplayName("H12.1.1 | Bits lesen") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_1_1_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "bitsPreState", JsonConverters::toBitInputStream, + "bufferPreState", JsonConverters::toMyByte, + "positionPreState", JsonNode::asInt, + "bitsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "bufferPostState", JsonConverters::toMyByte, + "positionPostState", JsonNode::asInt, + "expectedBit", JsonNode::asInt + ); + + @Override + public Class getTestClass() { + return BufferedBitInputStream.class; + } + + /** + * The field link for the buffer field. + */ + private FieldLink buffer; + + /** + * The field link for the position field. + */ + private FieldLink position; + + /** + * The underlying byte array input stream for the input stream to test. + */ + private @Nullable MockBitInputStream underlying; + + /** + * The input stream to test. + */ + private @Nullable BufferedBitInputStream stream; + + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + buffer = Links.getField(getType(), "buffer"); + position = Links.getField(getType(), "position"); + } + + @AfterEach + void tearDown() throws IOException { + if (underlying != null) { + underlying.close(); + } + if (stream != null) { + stream.close(); + } + } + + /** + * Initializes the test with the context. + * + * @param method the method to test + * @param parameters the parameters for the test + * + * @return the test information builder used to specify the test information + */ + private TestInformation.TestInformationBuilder initTest(MethodLink method, JsonParameterSet parameters) { + // Test setup + underlying = Objects.requireNonNull(parameters.get("bitsPreState")); + stream = new BufferedBitInputStream(underlying); + + MyByte bufferPreState = parameters.get("bufferPreState"); + buffer.set(stream, bufferPreState); + int positionPreState = parameters.get("positionPreState"); + position.set(stream, positionPreState); + + List bitsPostState = parameters.get("bitsPostState"); + MyByte bufferPostState = parameters.get("bufferPostState"); + int positionPostState = parameters.get("positionPostState"); + + return testInformation(method) + .preState( + TestInformation.builder() + .add("underlying", underlying.getBits()) + .add("buffer", bufferPreState) + .add("position", positionPreState) + .build() + ) + .postState( + TestInformation.builder() + .add("underlying", bitsPostState) + .add("buffer", bufferPostState) + .add("position", positionPostState) + .build() + ); + } + + /** + * Asserts the fetch() method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + void assertFetch(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("fetch"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + method.invoke(stream); + + // Test evaluation + MyByte bufferPostState = parameters.get("bufferPostState"); + int positionPostState = parameters.get("positionPostState"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + Context context = builder.actualState( + TestInformation.builder() + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(bufferPostState, bufferActualState, context, comment -> "Buffer is not updated correctly."); + Assertions2.assertEquals(positionPostState, positionActualState, context, + comment -> "Position is not updated correctly."); + } + + @DisplayName("Die Methode fetch() aktualisiert im Falle von nicht EOF den Puffer und die Position korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testFetchNotEOF.json", customConverters = CUSTOM_CONVERTERS) + void testFetchNotEOF(JsonParameterSet parameters) throws Throwable { + assertFetch(parameters); + } + + @DisplayName("Die Methode fetch() aktualisiert im Falle von EOF den Puffer und die Position korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testFetchEOF.json", customConverters = CUSTOM_CONVERTERS) + void testFetchEOF(JsonParameterSet parameters) throws Throwable { + assertFetch(parameters); + } + + /** + * Asserts the readBit() method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurso + */ + private void assertReadBit(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("readBit"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + int actualBit = method.invoke(stream); + + // Test evaluation + int expectedBit = parameters.get("expectedBit"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + Context context = builder.actualState( + TestInformation.builder() + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(expectedBit, actualBit, context, + comment -> "Return value is not correct."); + } + + @DisplayName("Die Methode readBit() liest das nächste Bit korrekt, falls wir bereits alle Bits des vorherigen Bytes gelesen haben.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitNextByte.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitNextByte(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von Lesen des ersten Bit das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitBufferStart.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitByteStart(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von Lesen eines mittleren Bit das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitBufferMiddle.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitByteMiddle(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von Lesen des letzen Bit eines Bytes das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitBufferEnd.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitByteEnd(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + @DisplayName("Die Methode readBit() gibt im Falle von EOF das korrekte Bit zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadBitEOF.json", customConverters = CUSTOM_CONVERTERS) + void testReadBitEOF(JsonParameterSet parameters) throws Throwable { + assertReadBit(parameters); + } + + /** + * Asserts that the method read() returns the correct result. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + private void assertRead(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("read"); + + // Test setup + TestInformation.TestInformationBuilder builder = initTest(method, parameters); + + // Test execution + int actualByte = method.invoke(stream); + + // Test evaluation + int expectedByte = parameters.get("expectedByte"); + MyByte bufferActualState = buffer.get(stream); + int positionActualState = position.get(stream); + + Context context = builder.actualState( + TestInformation.builder() + .add("buffer", bufferActualState) + .add("position", positionActualState) + .build() + ).build(); + + Assertions2.assertEquals(expectedByte, actualByte, context, comment -> "Return value is not correct."); + } + + @DisplayName("Die Methode read() gibt das korrekte Ergebnis zurück, falls wir am Ende des Streams sind.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadEnd.json", customConverters = CUSTOM_CONVERTERS) + void testReadEnd(JsonParameterSet parameters) throws Throwable { + assertRead(parameters); + } + + @DisplayName("Die Methode read() gibt das korrekte Teilergebnis zurück, falls der Stream keine 8 Bits mehr enthält.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testReadPartial.json", customConverters = CUSTOM_CONVERTERS) + void testReadPartial(JsonParameterSet parameters) throws Throwable { + assertRead(parameters); + } + + @DisplayName("Die Methode read() gibt in allen anderen Fallen das korrekte Ergebnis zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_1_testRead.json", customConverters = CUSTOM_CONVERTERS) + void testRead(JsonParameterSet parameters) throws Throwable { + assertRead(parameters); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java b/solution/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java new file mode 100644 index 0000000..e06f846 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/H12_2_1_TestsPublic.java @@ -0,0 +1,233 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.Links; +import h12.assertions.TestConstants; +import h12.io.compress.rle.BitRunningLengthCompressor; +import h12.mock.MockBitInputStream; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H12.1.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.2.1 | BitRunningLengthCompressor") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_2_1_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "bit", JsonNode::asInt, + "count", JsonNode::asInt, + "bitsPreState", JsonConverters::toBitInputStream, + "lastReadPreState", JsonNode::asInt, + "bitsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "lastReadPostState", JsonNode::asInt, + "startBits", node -> JsonConverters.toList(node, JsonNode::asInt), + "counts", node -> JsonConverters.toList(node, JsonNode::asInt), + "compressedBits", node -> JsonConverters.toList(node, JsonNode::asInt) + ); + + /** + * The compressor to test. + */ + private @Nullable BitRunningLengthCompressor compressor; + + /** + * The field link for the lastRead field. + */ + private FieldLink lastRead; + + @Override + public Class getTestClass() { + return BitRunningLengthCompressor.class; + } + + @BeforeAll + protected void globalSetup() { + super.globalSetup(); + lastRead = Links.getField(getType(), "lastRead"); + } + + @AfterEach + void tearDown() throws Exception { + if (compressor != null) { + compressor.close(); + } + } + + /** + * Asserts the getBitCount() method. + * + * @param parameters the parameters for the test + * + * @throws Throwable if an error occurs + */ + private void assertGetBitCount(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("getBitCount", int.class); + + // Test setup + MockBitInputStream in = parameters.get("bitsPreState"); + int lastReadPreState = parameters.getInt("lastReadPreState"); + MockBitOutputStream out = new MockBitOutputStream(); + compressor = new BitRunningLengthCompressor(in, out); + lastRead.set(compressor, lastReadPreState); + List bitsPostState = parameters.get("bitsPostState"); + int lastReadPostState = parameters.getInt("lastReadPostState"); + int bit = parameters.getInt("bit"); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", in.getBits()) + .add("out", List.of()) + .add("lastRead", lastReadPreState) + .add("bit", bit) + .build() + ) + .postState( + TestInformation.builder() + .add("in", bitsPostState) + .add("out", List.of()) + .add("lastRead", lastReadPostState) + .build() + ); + + // Test execution + int actualCount = method.invoke(compressor, bit); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + int expectedCount = parameters.getInt("count"); + int lastReadActual = lastRead.get(compressor); + + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getRemainingBits()) + .add("out", List.of()) + .add("lastRead", lastReadActual) + .build() + ).build(); + + Assertions2.assertEquals(lastReadPostState, lastReadActual, context, + comment -> "Last read bit is not updated correctly."); + Assertions2.assertEquals(expectedCount, actualCount, context, + comment -> "Computation of the count is incorrect."); + } + + @DisplayName("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits nichtmaximal ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_Tests_testGetBitCountNotMax.json", customConverters = CUSTOM_CONVERTERS) + void testGetBitCountNotMax(JsonParameterSet parameters) throws Throwable { + assertGetBitCount(parameters); + } + + @DisplayName("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits maximal ist.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_Tests_testGetBitCountMax.json", customConverters = CUSTOM_CONVERTERS) + void testGetBitCountMax(JsonParameterSet parameters) throws Throwable { + assertGetBitCount(parameters); + } + + @DisplayName("Die Methode compress() komprimiert korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_1_Tests_testCompress.json", customConverters = CUSTOM_CONVERTERS) + void testCompress(JsonParameterSet parameters) throws IOException { + // Access method to test + MethodLink method = Links.getMethod(getType(), "compress"); + + // Test setup + MockBitInputStream in = parameters.get("bitsPreState"); + int lastReadPreState = parameters.getInt("lastReadPreState"); + List bitsPostState = parameters.get("bitsPostState"); + int lastReadPostState = parameters.getInt("lastReadPostState"); + MockBitOutputStream out = new MockBitOutputStream(); + List compressedBits = parameters.get("compressedBits"); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", in.getBits()) + .add("out", out.getBits()) + .add("lastRead", lastReadPreState) + .build() + ) + .postState( + TestInformation.builder() + .add("in", bitsPostState) + .add("out", compressedBits) + .add("lastRead", lastReadPostState) + .build() + ); + + // Test execution + List startBits = parameters.get("startBits"); + List counts = parameters.get("counts"); + + // Custom gitBitCount to make the evaluation of compress() independent of getBitCount() + compressor = new BitRunningLengthCompressor(in, out) { + private int i = 0; + + @Override + protected int getBitCount(int bit) throws IOException { + int startBit = startBits.get(i); + int count = counts.get(i); + Assertions2.assertEquals(startBit, bit, builder.build(), + comment -> "Unexpected call of getBitCount(%s)".formatted(bit)); + if (i + 1 < counts.size()) { + lastRead.set(this, startBits.get(i + 1)); + } else { + lastRead.set(this, -1); + } + i++; + return count; + } + }; + compressor.compress(); + + // Test evaluation + int lastReadActual = lastRead.get(compressor); + Context context = builder.actualState( + TestInformation.builder() + .add("in", in.getRemainingBits()) + .add("out", out.getBits()) + .add("lastRead", lastReadActual) + .build() + ).build(); + + Assertions2.assertTrue(out.isFlushed(), context, + comment -> "The output stream is not flushed."); + Assertions2.assertEquals(compressedBits, out.getBits(), context, + comment -> "The compressed bits are incorrect."); + Assertions2.assertEquals(lastReadPostState, lastReadActual, context, + comment -> "Last read bit is not updated correctly."); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java b/solution/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java new file mode 100644 index 0000000..6d15662 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/H12_3_2_TestsPublic.java @@ -0,0 +1,188 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.huffman.HuffmanCoding; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.opentest4j.AssertionFailedError; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Defines the public tests for H12.3.2. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.3.2 | Huffman-Baum") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_3_2_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "elementsPreState", node -> JsonConverters.toList(node, JsonNode::asInt), + "elementsPostState", node -> JsonConverters.toList(node, JsonNode::asInt), + "minimumElement", JsonNode::asInt + ); + + @Override + public Class getTestClass() { + return HuffmanCoding.class; + } + + @DisplayName("Die Methode removeMin(Collection elements, Comparator cmp) entfernt das Minimum und gibt diesen korrekt zurück.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_3_2_Tests_testRemoveMin.json", customConverters = CUSTOM_CONVERTERS) + public void testRemoveMin(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("removeMin", Collection.class, Comparator.class); + + // Test setup + List elementsPreState = new ArrayList<>(parameters.get("elementsPreState")); + List elementsPostState = new ArrayList<>(parameters.get("elementsPostState")); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("elements", elementsPreState) + .add("cmp", COMPARATOR) + .build() + ) + .postState( + TestInformation.builder() + .add("elements", elementsPostState) + .build() + ); + + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + List elementsActualState = new ArrayList<>(elementsPreState); + Integer removed = method.invoke(coding, elementsActualState, COMPARATOR); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("elements", elementsPreState) + .build() + ).build(); + + int minimumElement = parameters.getInt("minimumElement"); + Assertions2.assertEquals(minimumElement, removed, context, comment -> "Removed element is incorrect."); + Assertions2.assertEquals(elementsPostState, elementsActualState, context, + comment -> "Remaining elements are incorrect."); + } + + @DisplayName("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) erstellt die Elemente mit der Funktion f korrekt.") + @Test + void testBuildFunctionF() throws Throwable { + // Access method to test + MethodLink method = getMethod("build", Map.class, BiFunction.class, BiFunction.class, Comparator.class); + + // Test setup + Map frequency = Map.of('a', 1, 'b', 2, 'c', 3); + List visited = new ArrayList<>(); + BiFunction f = (c, i) -> { + visited.add(c); + return c; + }; + BiFunction g = (a, b) -> a; + + Context context = testInformation(method).preState( + TestInformation.builder() + .add("frequency", frequency) + .add("f", "f: (Character, Integer) -> Mark character as visited") + .add("g", "g: (Character, Character) -> Character") + .add("cmp", COMPARATOR) + .build() + ).build(); + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + Exception ex = null; + try { + method.invoke(coding, frequency, f, g, COMPARATOR); + } catch (Exception e) { + ex = e; + } + + // Test evaluation + try { + Assertions2.assertEquals(frequency.keySet().stream().toList(), visited, context, + comment -> "Function f was not called with the correct elements."); + } catch (AssertionFailedError e) { + if (ex != null) { + throw ex; + } else { + throw e; + } + } + } + + @DisplayName("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) wendet die Funktion g mit den beiden Minimumelementen korrekt an.") + @Test + void testBuildFunctionG() throws Throwable { + // Access the method to test + MethodLink method = getMethod("build", Map.class, BiFunction.class, BiFunction.class, Comparator.class); + + // Test setup + Map frequency = Map.of('a', 1, 'b', 2, 'c', 3); + List> visited = new ArrayList<>(); + BiFunction f = (c, i) -> c; + BiFunction g = (a, b) -> { + visited.add(Map.entry(a, b)); + return a; + }; + List> expected = List.of(Map.entry('a', 'b'), Map.entry('a', 'c')); + + Context context = testInformation(method).preState( + TestInformation.builder() + .add("frequency", frequency) + .add("f", "f: (Character, Integer) -> Mark pair (Character, Character) as visited") + .add("g", "g: (Character, Character) -> (Character, Character)") + .add("cmp", COMPARATOR) + .build() + ).build(); + + + // Test execution + HuffmanCoding coding = new HuffmanCoding(); + Exception ex = null; + try { + method.invoke(coding, frequency, f, g, Comparator.naturalOrder()); + } catch (Exception e) { + ex = e; + } + + // Test evaluation + try { + Assertions2.assertEquals(expected, visited, context, + comment -> "Function g was not called with the correct elements."); + } catch (AssertionFailedError e) { + if (ex != null) { + throw ex; + } else { + throw e; + } + } + } +} diff --git a/solution/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java b/solution/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java new file mode 100644 index 0000000..6f4044e --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/H12_4_1_TestsPublic.java @@ -0,0 +1,238 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.assertions.TestConstants; +import h12.io.compress.EncodingTable; +import h12.io.compress.huffman.HuffmanCodingCompressor; +import h12.mock.MockBitOutputStream; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Defines the public tests for H12.4.1. + * + * @author Nhan Huynh + */ +@TestForSubmission +@DisplayName("H12.4.1 | Huffman-Komprimierung") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public class H12_4_1_TestsPublic extends H12_Tests { + + /** + * The custom converters for the JSON parameter set test annotation. + */ + public static final Map> CONVERTERS = Map.of( + "text", JsonNode::asText, + "compressed", node -> JsonConverters.toList(node, JsonNode::asInt), + "encodingTable", JsonConverters::toEncodingTable + ); + + /** + * The compressor instance used for testing. + */ + private @Nullable HuffmanCodingCompressor compressor; + + @AfterEach + void tearDown() throws Exception { + if (compressor != null) { + compressor.close(); + } + } + + @Override + public Class getTestClass() { + return HuffmanCodingCompressor.class; + } + + private String unifiedLineEndings(String text) { + return text.replace("\r\n", "\n"); + } + + @DisplayName("Die Methode getText() liest den Text korrekt ein.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testGetText.json", customConverters = CUSTOM_CONVERTERS) + void testGetText(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("getText"); + + // Test setup + String text = parameters.getString("text"); + text = unifiedLineEndings(text); + + TestInformation.TestInformationBuilder builder = testInformation(method) + .preState( + TestInformation.builder() + .add("in", text) + .add("out", List.of()) + .build() + ) + .postState( + TestInformation.builder() + .add("out", List.of()) + .build() + ); + + // Test execution + ByteArrayInputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + MockBitOutputStream out = new MockBitOutputStream(); + compressor = new HuffmanCodingCompressor(in, out); + String result = method.invoke(compressor); + result = unifiedLineEndings(result); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("out", out.getBits()) + .build() + ).build(); + + // Validate the output + Assertions2.assertEquals(text, result, context, comment -> "The read text is incorrect."); + } + + @DisplayName("Die Methode computeTextSize(String text, EncodingTable encodingTable) berechnet die Anzahl an Bits, die für die Komprimierung des Textes nötig ist, korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testComputeTextSize.json", customConverters = CUSTOM_CONVERTERS) + void testComputeTextSize(JsonParameterSet parameters) throws Throwable { + // Access method to test + MethodLink method = getMethod("computeTextSize", String.class, EncodingTable.class); + + // Test setup + String text = parameters.getString("text"); + EncodingTable encodingTable = parameters.get("encodingTable"); + + Context context = testInformation(method) + .preState( + TestInformation.builder() + .add("text", text) + .add("encodingTable", encodingTable) + .build() + ).build(); + + // Test the method + compressor = new HuffmanCodingCompressor(new ByteArrayInputStream(new byte[0]), new MockBitOutputStream()); + int result = method.invoke(compressor, text, encodingTable); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + int textSize = parameters.getInt("textSize"); + Assertions2.assertEquals(textSize, result, context, comment -> "Computed text size is incorrect."); + } + + @DisplayName("Die Methode encodeContent(String text, EncodingTable encodingTable) komprimiert den Text korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testEncodeText.json", customConverters = CUSTOM_CONVERTERS) + void testEncodeText(JsonParameterSet parameters) throws Throwable { + // Access the method to test + MethodLink method = getMethod("encodeText", String.class, EncodingTable.class); + + // Test setup + String text = parameters.getString("text"); + EncodingTable encodingTable = parameters.get("encodingTable"); + List compressed = parameters.get("compressed"); + InputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + MockBitOutputStream out = new MockBitOutputStream(); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .add("encodingTable", encodingTable) + .add("out", out.getBits()) + .build() + ).postState( + TestInformation.builder() + .add("out", compressed) + .build() + ); + + // Test execution + compressor = new HuffmanCodingCompressor(in, out); + method.invoke(compressor, text, encodingTable); + + // Close it to flush the output + assert compressor != null; + compressor.close(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("out", out.getBits()) + .build() + ).build(); + + Assertions2.assertEquals(compressed, out.getBits(), context, comment -> "The compressed data is incorrect."); + } + + @DisplayName("Die Methode compress() ist vollständig und korrekt.") + @ParameterizedTest + @JsonParameterSetTest(value = "H12_4_1_testCompress.json", customConverters = CUSTOM_CONVERTERS) + void testCompress(JsonParameterSet parameters) throws IOException { + // Access method to test + MethodLink method = getMethod("compress"); + + // Test setup + String text = parameters.getString("text"); + EncodingTable encodingTable = parameters.get("encodingTable"); + List compressed = parameters.get("compressed"); + InputStream in = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); + MockBitOutputStream out = new MockBitOutputStream(); + + TestInformation.TestInformationBuilder builder = testInformation(method).preState( + TestInformation.builder() + .add("text", text) + .add("encodingTable", encodingTable) + .add("out", out.getBits()) + .build() + ).postState( + TestInformation.builder() + .add("out", compressed) + .build() + ); + + // Test execution + compressor = new HuffmanCodingCompressor(in, out) { + + @Override + protected String getText() throws IOException { + return unifiedLineEndings(super.getText()); + } + }; + compressor.compress(); + + // Test evaluation + Context context = builder.actualState( + TestInformation.builder() + .add("out", out.getBits()) + .build() + ).build(); + Assertions2.assertTrue(out.isFlushed(), context, + comment -> "The output stream is not flushed."); + Assertions2.assertEquals(compressed, out.getBits(), context, comment -> "The compressed data is incorrect."); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java b/solution/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java new file mode 100644 index 0000000..7152a1c --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/H12_RubricProviderPublic.java @@ -0,0 +1,18 @@ +package h12; + +import h12.rubric.H12_RubricProvider; + +/** + * A public rubric provider for H12. + * + * @author Nhan Huynh + */ +public class H12_RubricProviderPublic extends H12_RubricProvider { + + /** + * Constructs a new public rubric provider. + */ + public H12_RubricProviderPublic() { + super(true); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/H12_Tests.java b/solution/H12/src/graderPublic/java/h12/H12_Tests.java new file mode 100644 index 0000000..82209f7 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/H12_Tests.java @@ -0,0 +1,138 @@ +package h12; + +import h12.assertions.Links; +import h12.assertions.TestConstants; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.sourcegrade.jagr.api.rubric.TestForSubmission; +import org.tudalgo.algoutils.tutor.general.annotation.SkipAfterFirstFailedTest; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +/** + * Defines a test skeleton for the H10 assignment. + * + *

Use the following schema: + *

{@code
+ *     public class TestClass extends H12_Test {
+ *
+ *          public static final Map> CUSTOM_CONVERTERS = Map.of(
+ *              ...
+ *          );
+ *
+ *          @Override
+ *          public Class getClassType() {
+ *              return ...
+ *          }
+ *
+ *          @ParameterizedTest
+ *          @JsonParameterSetTest(value = "path-to-json-data.json", customConverters = CUSTOM_CONVERTERS)
+ *          void testXYZ(JsonParameterSet parameters) {
+ *              ...
+ *          }
+ *   }
+ * }
+ * + * @author Nhan Huynh + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@TestForSubmission +@SkipAfterFirstFailedTest(TestConstants.SKIP_AFTER_FIRST_FAILED_TEST) +public abstract class H12_Tests { + + /** + * The attribute name for custom converters in the JSON parameter set test annotation. + */ + public static final String CUSTOM_CONVERTERS = "CONVERTERS"; + + /** + * The custom comparator for comparing integers. + */ + public static final Comparator COMPARATOR = new Comparator() { + + private static final Comparator delegate = Comparator.naturalOrder(); + + @Override + public int compare(Integer o1, Integer o2) { + return delegate.compare(o1, o2); + } + + @Override + public String toString() { + return "o1 <= o2"; + } + }; + + /** + * The type of the class under test. + */ + private @Nullable TypeLink type; + + /** + * Configuration for all tests. + */ + @BeforeAll + protected void globalSetup() { + Assertions.assertNotNull( + getClass().getAnnotation(TestForSubmission.class), + "The test class is not annotated with @TestForSubmission which is needed for Jagr to work" + ); + this.type = Links.getType(getTestClass()); + } + + /** + * Returns the class type of the class under test. + * + * @return the class type of the class under test + */ + public abstract Class getTestClass(); + + /** + * Returns the method under test. + * + * @param methodName the name of the method + * @param parameterClasses the parameter classes of the method + * + * @return the method under test + */ + public MethodLink getMethod(String methodName, Class... parameterClasses) { + List parameterTypes = Arrays.stream(parameterClasses).map(BasicTypeLink::of).toList(); + return Links.getMethod( + type, + methodName, + Matcher.of(method -> method.typeList().equals(parameterTypes)) + ); + } + + /** + * Returns the type of the class under test. + * + * @return the type of the class under test + */ + public TypeLink getType() { + if (type == null) { + throw new IllegalStateException("Class of the test method not set"); + } + return type; + } + + /** + * Returns a context builder with the method under test as the subject. + * + * @param methodLink the method under test + * + * @return a context builder with the method under test as the subject + */ + public TestInformation.TestInformationBuilder testInformation(MethodLink methodLink) { + return TestInformation.builder() + .subject(methodLink.reflection()); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/JsonConverters.java b/solution/H12/src/graderPublic/java/h12/JsonConverters.java new file mode 100644 index 0000000..16cc085 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/JsonConverters.java @@ -0,0 +1,95 @@ +package h12; + +import com.fasterxml.jackson.databind.JsonNode; +import h12.io.compress.EncodingTable; +import h12.lang.MyBit; +import h12.lang.MyByte; +import h12.mock.MockBitInputStream; +import h12.mock.MockHuffmanEncodingTable; +import org.jetbrains.annotations.Nullable; + +/** + * Utility class for JSON converters. + * + * @author Nhan Huynh + */ +public final class JsonConverters extends org.tudalgo.algoutils.tutor.general.json.JsonConverters { + + /** + * Prevent instantiation of this utility class. + */ + private JsonConverters() { + + } + + public static @Nullable MyByte toMyByte(JsonNode node) { + + if (!node.isInt() && !node.isNull()) { + throw new IllegalStateException("JSON node is not an integer"); + } + if (node.isNull()) { + return null; + } + return new MyByte(node.asInt()); + } + + /** + * Converts the given JSON node to a bit input stream. + * + * @param node the JSON node to convert + * + * @return the bit input stream + */ + public static MockBitInputStream toBitInputStream(JsonNode node) { + if (!node.isArray()) { + throw new IllegalStateException("JSON node is not an array"); + } + return new MockBitInputStream(toList(node, JsonNode::asInt)); + } + + /** + * Converts the given JSON node to an encoding table. + * + * @param node the JSON node to convert + * + * @return the encoding table + */ + public static EncodingTable toEncodingTable(JsonNode node) { + if (!node.isObject()) { + throw new IllegalStateException("JSON node is not an object"); + } + return new MockHuffmanEncodingTable(toMap(node, keyMapper -> keyMapper.charAt(0), JsonNode::asText)); + } + + /** + * Converts a JSON node to a byte array. + * + * @param node the JSON node containing the bytes + * + * @return the byte array + */ + public static byte[] toByteArray(JsonNode node) { + if (!node.isArray()) { + throw new IllegalStateException("JSON node is not an array"); + } + byte[] bytes = new byte[node.size()]; + for (int i = 0; i < node.size(); i++) { + bytes[i] = (byte) node.get(i).asInt(); + } + return bytes; + } + + /** + * Converts a JSON node to a bit + * + * @param node the JSON node containing the bit + * + * @return the bit + */ + public static MyBit toBit(JsonNode node) { + if (!node.isInt()) { + throw new IllegalStateException("JSON node is not an int"); + } + return MyBit.fromInt(node.asInt()); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/TestInformation.java b/solution/H12/src/graderPublic/java/h12/TestInformation.java new file mode 100644 index 0000000..33f2cec --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/TestInformation.java @@ -0,0 +1,234 @@ +package h12; + +import org.jetbrains.annotations.Nullable; +import org.tudalgo.algoutils.tutor.general.assertions.Assertions2; +import org.tudalgo.algoutils.tutor.general.assertions.Context; +import org.tudalgo.algoutils.tutor.general.assertions.Property; +import org.tudalgo.algoutils.tutor.general.assertions.basic.BasicProperty; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.ListIterator; + +/** + * Context information for a test. THis class extends the {@link Context} interface and provide optional pre-, post- and + * actual states of the test. + * + * @author Nhan Huynh + */ +public class TestInformation implements Context { + + /** + * The subject of the test. + */ + private final @Nullable Object subject; + + /** + * The properties of the test. + */ + private final Collection properties; + + /** + * Constructs new test information with the specified subject and properties. + * + * @param subject the subject of the test + * @param preState the pre-state of the test + * @param postState the post-state of the test + * @param actualState the actual state of the test + * @param properties the properties of the test + */ + public TestInformation( + @Nullable Object subject, + @Nullable TestInformation preState, + @Nullable TestInformation postState, + @Nullable TestInformation actualState, + Collection properties) { + + + Context.Builder builder = Assertions2.contextBuilder() + .subject(subject); + + if (preState != null) { + addState(builder, "Pre state", preState); + } + if (postState != null) { + addState(builder, "Post state", postState); + } + if (actualState != null) { + addState(builder, "Actual state", actualState); + } + builder.add(properties.toArray(Property[]::new)); + Context context = builder.build(); + this.subject = context.subject(); + this.properties = context.properties(); + } + + /** + * Adds the state to the builder. + * + * @param builder the builder to add the sotate to + * @param name the name of the state + * @param state the state to add + */ + private void addState(Builder builder, String name, TestInformation state) { + if (state != null) { + builder.add( + name, + Assertions2.contextBuilder() + .add(state.properties.toArray(Property[]::new)) + .build() + ); + } + } + + /** + * Returns a new test information builder. + * + * @return a new test information builder + */ + public static TestInformationBuilder builder() { + return new TestInformationBuilderImpl(); + } + + @Override + public Object subject() { + return subject; + } + + @Override + public Collection properties() { + return properties; + } + + /** + * Builder for {@link TestInformation}. + */ + public interface TestInformationBuilder extends h12.rubric.Builder { + + /** + * Sets the subject of the test. + * + * @param subject the subject of the test + * + * @return this builder after setting the subject + */ + TestInformationBuilder subject(Object subject); + + /** + * Sets the pre-state of the test. + * + * @param preState the pre-state of the test + * + * @return this builder after setting the pre-state + */ + TestInformationBuilder preState(TestInformation preState); + + /** + * Sets the post-state of the test. + * + * @param postState the post-state of the test + * + * @return this builder after setting the post-state + */ + TestInformationBuilder postState(TestInformation postState); + + /** + * Sets the actual state of the test. + * + * @param actualState the actual state of the test + * + * @return this builder after setting the actual state + */ + TestInformationBuilder actualState(TestInformation actualState); + + /** + * Adds a property to the test which provides context information. + * + * @param key the key of the property + * @param value the value of the property + * + * @return this builder after adding the property + */ + TestInformationBuilder add(String key, Object value); + } + + /** + * Implementation of the {@link TestInformationBuilder} interface. + */ + private static class TestInformationBuilderImpl implements TestInformationBuilder { + + /** + * The subject of the test. + */ + private @Nullable Object subject; + + /** + * The pre-state of the test. + */ + private @Nullable TestInformation preState = null; + + /** + * The post-state of the test. + */ + private @Nullable TestInformation postState = null; + + /** + * The actual state of the test. + */ + private @Nullable TestInformation actualState = null; + + /** + * The properties of the test. + */ + private final List properties = new ArrayList<>(); + + @Override + public TestInformationBuilder subject(Object subject) { + this.subject = subject; + return this; + } + + @Override + public TestInformationBuilder preState(TestInformation preState) { + this.preState = preState; + return this; + } + + @Override + public TestInformationBuilder postState(TestInformation postState) { + this.postState = postState; + return this; + } + + @Override + public TestInformationBuilder actualState(TestInformation actualState) { + this.actualState = actualState; + return this; + } + + @Override + public TestInformationBuilder add(String key, Object value) { + ListIterator iterator = properties.listIterator(); + while (iterator.hasNext()) { + Property property = iterator.next(); + if (property.key().equals(key)) { + iterator.set(new BasicProperty(key, value)); + return this; + } + } + properties.add(new BasicProperty(key, value)); + return this; + } + + @Override + public TestInformation build() { + return new TestInformation( + subject, + preState, + postState, + actualState, + properties); + } + } +} diff --git a/solution/H12/src/graderPublic/java/h12/assertions/Links.java b/solution/H12/src/graderPublic/java/h12/assertions/Links.java new file mode 100644 index 0000000..cae0faa --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/assertions/Links.java @@ -0,0 +1,80 @@ +package h12.assertions; + +import org.tudalgo.algoutils.tutor.general.assertions.Assertions3; +import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers; +import org.tudalgo.algoutils.tutor.general.match.Matcher; +import org.tudalgo.algoutils.tutor.general.match.MatcherFactories; +import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink; +import org.tudalgo.algoutils.tutor.general.reflections.FieldLink; +import org.tudalgo.algoutils.tutor.general.reflections.MethodLink; +import org.tudalgo.algoutils.tutor.general.reflections.TypeLink; + +import java.util.Arrays; + +/** + * Utility class for links to classes and methods. + * + * @author Nhan Huynh + */ +public final class Links { + + /** + * Matcher factory for string matchers. + */ + private static final MatcherFactories.StringMatcherFactory STRING_MATCHER_FACTORY = BasicStringMatchers::identical; + + /** + * Prevent instantiation of this utility class. + */ + private Links() { + + } + + /** + * Returns the type link for the given class. + * + * @param clazz the class to get the type from + * + * @return the type link for the given class + */ + public static TypeLink getType(Class clazz) { + return Assertions3.assertTypeExists( + BasicPackageLink.of(clazz.getPackageName()), + STRING_MATCHER_FACTORY.matcher(clazz.getSimpleName()) + ); + } + + /** + * Returns the field link for the given type and field name. + * + * @param type the type to get the field from + * @param methodName the name of the field + * @param matchers the matchers for additional checks to retrieve the field + * + * @return the field link for the given type and field name + */ + @SafeVarargs + public static FieldLink getField(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertFieldExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } + + /** + * Returns the method link for the given type and method name. + * + * @param type the type to get the method from + * @param methodName the name of the method + * @param matchers the matchers for additional checks to retrieve the method + * + * @return the method link for the given type and method name + */ + @SafeVarargs + public static MethodLink getMethod(TypeLink type, String methodName, Matcher... matchers) { + return Assertions3.assertMethodExists( + type, + Arrays.stream(matchers).reduce(STRING_MATCHER_FACTORY.matcher(methodName), Matcher::and) + ); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/assertions/TestConstants.java b/solution/H12/src/graderPublic/java/h12/assertions/TestConstants.java new file mode 100644 index 0000000..70d9791 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/assertions/TestConstants.java @@ -0,0 +1,25 @@ +package h12.assertions; + +/** + * Constants for tests for configuring test behavior. + * + * @author Nhan Huynh + */ +public final class TestConstants { + + /** + * Timeout for tests in seconds. + */ + public static final int TEST_TIMEOUT_IN_SECONDS = 2; + + /** + * Skip after the first failed test. + */ + public static final boolean SKIP_AFTER_FIRST_FAILED_TEST = true; + + /** + * Prevent instantiation of this utility class. + */ + private TestConstants() { + } +} diff --git a/solution/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java b/solution/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java new file mode 100644 index 0000000..ba47d63 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/mock/MockBitInputStream.java @@ -0,0 +1,105 @@ +package h12.mock; + +import h12.io.BitInputStream; +import h12.lang.MyBit; +import h12.lang.MyByte; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.IntStream; + +/** + * A mock bit input stream for testing purposes. This implementation allows us to define which bits to read. + * + * @author Nhan Huynh + */ +public class MockBitInputStream extends BitInputStream { + + /** + * The bits to read. + */ + private final List bits; + + /** + * The iterator for reading the bits. + */ + private Iterator read; + + /** + * Creates a new mock bit input stream with the given bits. + * + * @param bits the bits to read + */ + public MockBitInputStream(List bits) { + this.bits = bits; + this.read = bits.iterator(); + } + + /** + * Creates a new mock bit input stream with the given bits. + * + * @param bits the bits to read + */ + public MockBitInputStream(Integer... bits) { + this(Arrays.asList(bits)); + } + + @Override + public int readBit() throws IOException { + if (!read.hasNext()) { + return -1; + } + return read.next(); + } + + @Override + public int read() throws IOException { + if (!read.hasNext()) { + return -1; + } + MyByte value = new MyByte(); + int low = 0; + int high = MyByte.NUMBER_OF_BITS - 1; + IntStream.rangeClosed(low, high).forEach(i -> value.set(high - i, MyBit.fromInt(read.next()))); + return value.intValue(); + } + + /** + * Returns the bits that this mock bit input stream can read. + * + * @return the bits that this mock bit input stream can read + */ + public List getBits() { + return bits; + } + + /** + * Returns the remaining bits that this mock bit input stream can read. + * + * @return the remaining bits that this mock bit input stream can read + */ + public List getRemainingBits() { + List remainingBits = new ArrayList<>(); + read.forEachRemaining(remainingBits::add); + setRemainingBits(remainingBits); + return remainingBits; + } + + /** + * Sets the remaining bits that this mock bit input stream can read. + * + * @param elements the remaining bits to read + */ + public void setRemainingBits(Iterable elements) { + this.read = elements.iterator(); + } + + @Override + public String toString() { + return bits.toString(); + } +} + diff --git a/solution/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java b/solution/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java new file mode 100644 index 0000000..a3ebdd0 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/mock/MockBitOutputStream.java @@ -0,0 +1,94 @@ +package h12.mock; + +import h12.io.BitOutStream; +import h12.lang.MyBit; +import h12.lang.MyByte; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * A mock bit output stream for testing purposes. This implementation allows us to access the written bits directly. + * + * @author Nhan Huynh + */ +public class MockBitOutputStream extends BitOutStream { + + /** + * The bits written to the stream. + */ + private final List bits = new ArrayList<>(); + + /** + * Whether the stream has been flushed. + */ + private boolean flushed; + + @Override + public void writeBit(MyBit bit) throws IOException { + bits.add(bit.intValue()); + } + + @Override + public void write(int b) throws IOException { + MyByte value = new MyByte(b); + for (int i = MyByte.NUMBER_OF_BITS - 1; i >= 0; i--) { + bits.add(value.get(i).intValue()); + } + } + + /** + * Returns the bits written to the stream. + * + * @return the bits written to the stream + */ + public List getBits() { + if (!flushed) { + return List.of(); + } + return bits; + } + + /** + * Returns the bits written to the stream without flushing the stream. The output contains all + * bits written to the stream, even if the stream has not been flushed. + * + * @return the bits written to the stream without flushing the stream + */ + public List getBitsUnflushed() { + return bits; + } + + /** + * Returns whether the stream has been flushed. + * + * @return whether the stream has been flushed + */ + public boolean isFlushed() { + return flushed; + } + + @Override + public void flush() throws IOException { + super.flush(); + flushed = true; + } + + @Override + public void close() throws IOException { + super.close(); + flush(); + } + + @Override + public int hashCode() { + return Objects.hashCode(getBits()); + } + + @Override + public String toString() { + return bits.toString(); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java b/solution/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java new file mode 100644 index 0000000..00bd9bf --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/mock/MockHuffmanEncodingTable.java @@ -0,0 +1,82 @@ +package h12.mock; + +import h12.io.compress.EncodingTable; + +import java.util.Map; +import java.util.Objects; +import java.util.stream.StreamSupport; + +/** + * A mock implementation of the {@link EncodingTable} interface for testing purposes. + * + * @author Nhan Huynh + */ +public class MockHuffmanEncodingTable implements EncodingTable { + + /** + * The encodings of characters. + */ + private final Map encodings; + + /** + * Creates a new mock encoding table with the given encodings. + * + * @param encodings the encodings of characters + */ + public MockHuffmanEncodingTable(Map encodings) { + this.encodings = encodings; + } + + @Override + public boolean containsCharacter(Character character) { + return encodings.containsKey(character); + } + + @Override + public boolean containsCode(String code) { + return encodings.containsValue(code); + } + + @Override + public boolean containsCode(Iterable iterable) { + return containsCode(StreamSupport.stream(iterable.spliterator(), false) + .map(String::valueOf) + .reduce("", String::concat)); + } + + @Override + public String getCode(Character character) { + return encodings.get(character); + } + + @Override + public Character getCharacter(String code) { + return encodings.entrySet().stream() + .filter(entry -> entry.getValue().equals(code)) + .map(Map.Entry::getKey) + .findFirst() + .orElseThrow(); + } + + @Override + public Character getCharacter(Iterable iterable) { + return getCharacter(StreamSupport.stream(iterable.spliterator(), false) + .map(String::valueOf) + .reduce("", String::concat)); + } + + @Override + public boolean equals(Object o) { + return this == o || o instanceof MockHuffmanEncodingTable that && encodings.equals(that.encodings); + } + + @Override + public int hashCode() { + return Objects.hashCode(encodings); + } + + @Override + public String toString() { + return encodings.toString(); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/rubric/Builder.java b/solution/H12/src/graderPublic/java/h12/rubric/Builder.java new file mode 100644 index 0000000..901f4e5 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/rubric/Builder.java @@ -0,0 +1,18 @@ +package h12.rubric; + +/** + * A builder interface for building objects. + * + * @param the type of object to build + * + * @author Nhan Huynh + */ +public interface Builder { + + /** + * Builds the object. + * + * @return the built object + */ + T build(); +} diff --git a/solution/H12/src/graderPublic/java/h12/rubric/Criteriable.java b/solution/H12/src/graderPublic/java/h12/rubric/Criteriable.java new file mode 100644 index 0000000..e98659d --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/rubric/Criteriable.java @@ -0,0 +1,19 @@ +package h12.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; + +/** + * An object that implements this interface indicates that it can be converted to a {@link Criterion} which means + * it is gradable. + * + * @author Nhan Huynh + */ +public interface Criteriable { + + /** + * Returns the criterion that represents this object. + * + * @return the criterion that represents this object + */ + Criterion getCriterion(); +} diff --git a/solution/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java b/solution/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java new file mode 100644 index 0000000..25435d6 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/rubric/H12_RubricProvider.java @@ -0,0 +1,192 @@ +package h12.rubric; + +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Rubric; +import org.sourcegrade.jagr.api.rubric.RubricProvider; +import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +/** + * Provides the rubric for H10. + * + * @author Nhan Huynh + */ +public abstract class H12_RubricProvider implements RubricProvider { + + /** + * Defines the subtask H12.1.1 for task H12.1. + */ + private static final Subtask H12_1_1 = Subtask.builder() + .description("H12.1.1 | Bits lesen") + .testClassName("h12.H12_1_1_Tests") + .criterion("Die Methode fetch() aktualisiert den Puffer und die Position korrekt.", Map.of( + "testFetchNotEOF", List.of(JsonParameterSet.class), + "testFetchEOF", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode readBit() liest das nächste Byte korrekt, falls wir bereits alle Bits des vorherigen Bytes gelesen haben", "testReadBitNextByte", JsonParameterSet.class) + .criterion("Die Methode readBit() gibt in allen anderen Fällen das korrekte Bit zurück.", Map.of( + "testReadBitByteStart", List.of(JsonParameterSet.class), + "testReadBitByteMiddle", List.of(JsonParameterSet.class), + "testReadBitByteEnd", List.of(JsonParameterSet.class), + "testReadBitEOF", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode read() gibt das korrekte Ergebnis zurück, falls wir am Ende des Streams sind.", "testReadEnd", JsonParameterSet.class) + .criterion("Die Methode read() gibt das korrekte Teilergebnis zurück, falls der Stream keine 8 Bits mehr enthält.", "testReadPartial", JsonParameterSet.class) + .criterion("Die Methode read() gibt in allen anderen Fallen das korrekte Ergebnis zurück.", "testRead", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.1.2 for task H12.1. + */ + private static final Subtask H12_1_2 = Subtask.builder() + .description("H12.1.2 | Bits schreiben") + .testClassName("h12.H12_1_2_Tests") + .criterion("Die Methode flushBuffer() aktualisiert den Puffer und Position korrekt, wenn nötig.", false, Map.of( + "testFlushBufferUpdateYes", List.of(JsonParameterSet.class), + "testFlushBufferUpdateNo", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode flushBuffer() schreibt das Zeichen in den internen OutputStream korrekt.", false, "testFlushBufferWrite", JsonParameterSet.class) + .criterion("Die Methode writeBit(Bit bit) schreibt das Zeichen in den internen OutputStream, falls der Puffer voll ist.", false, Map.of( + "testWriteBitFlushYes", List.of(JsonParameterSet.class), + "testWriteBitFlushNo", List.of(JsonParameterSet.class) + )) + .criterion("Die Methode writeBit(Bit bit) schreibt ein Bit korrekt.", false, "testWriteBit", JsonParameterSet.class) + .criterion("Die Methode write(int b) schreibt ein Byte korrekt.", false, "testWrite", JsonParameterSet.class) + .criterion("Die Methode write(int b) wirft eine IllegalArgumentException, falls die Eingabe kein Byte ist.", false, "testWriteIllegalArgumentException", JsonParameterSet.class) + .build(); + + /** + * Defines the task H12.1. + */ + private static final Task H12_1 = Task.builder() + .description("H12.1 | Mit Bits jonglieren: Eingabe und Ausgabe im Detail") + .subtasks(H12_1_1, H12_1_2) + .build(); + + /** + * Defines the subtask H12.2.1 for task H12.2. + */ + private static final Subtask H12_2_1 = Subtask.builder() + .description("H12.2.1 | BitRunningLengthCompressor") + .testClassName("h12.H12_2_1_Tests") + .criterion("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits nicht maximal ist.", "testGetBitCountNotMax", JsonParameterSet.class) + .criterion("Die Methode getBitCount(int bit) gibt die korrekte Anzahl an aufeinanderfolgenden wiederholenden Bits zurück, für den Fall, dass die Anzahl der Bits maximal ist.", "testGetBitCountMax", JsonParameterSet.class) + .criterion("Die Methode compress() komprimiert korrekt.", "testCompress", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.2.2 for task H12.2. + */ + private static final Subtask H12_2_2 = Subtask.builder() + .description("H12.2.2 | BitRunningLengthDecompressor") + .testClassName("h12.H12_2_2_Tests") + .criterion("Die Methode writeBit(int count, Bit bit) schreibt die Anzahl an aufeinanderfolgenden wiederholenden Bits korrekt.", false, "testWriteBit", JsonParameterSet.class) + .criterion("Die Methode decompress() liest die Anzahl an aufeinanderfolgenden wiederholenden Bits.", false, "testDecompressBitCount", JsonParameterSet.class) + .criterion("Die Methode decompress() dekomprimiert korrekt.", false, "testDecompress", JsonParameterSet.class) + .build(); + + /** + * Defines the task H12.2. + */ + private static final Task H12_2 = Task.builder() + .description("H12.3 | My Heart Skips Skips Skips, Skips Skips Skips a Bit") + .subtasks(H12_2_1, H12_2_2) + .build(); + + /** + * Defines the subtask H12.3.1 for task H12.3. + */ + private static final Subtask H12_3_1 = Subtask.builder() + .description("H12.3.1 | Häufigkeitstabelle") + .testClassName("h12.H12_3_1_Tests") + .criterion("Die Methode buildFrequencyTable(String text) erstellt die Häufigkeitstabelle mit allen Zeichen als Schlüssel korrekt.", false, "testBuildFrequencyTableKeys", JsonParameterSet.class) + .criterion("Die Methode buildFrequencyTable(String text) erstellt die Häufigkeitstabelle mt den Häufigkeiten korrekt.", false, "testResult", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.3.2 for task H12.3. + */ + private static final Subtask H12_3_2 = Subtask.builder() + .description("H12.3.2 | Huffman-Baum") + .testClassName("h12.H12_3_2_Tests") + .criterion("Die Methode removeMin(Collection elements, Comparator cmp) entfernt das Minimum und gibt diesen korrekt zurück.", "testRemoveMin", JsonParameterSet.class) + .criterion("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) erstellt die Elemente mit der Funktion f korrekt.", "testBuildFunctionF") + .criterion("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) wendet die Funktion g mit den beiden Minimumelementen korrekt an.", "testBuildFunctionG") + .criterion("Die Methode build(Map frequency, BiFunction f, BiFunction g, Comparator cmp) ist vollständig und korrekt.", false, "testResult") + .build(); + + /** + * Defines the task H12.3. + */ + private static final Task H12_3 = Task.builder() + .description("H12.3 | Die Kunst des Codes: Huffman-Coding I") + .subtasks(H12_3_1, H12_3_2) + .build(); + + /** + * Defines the subtask H12.4.1 for task H12.4. + */ + private static final Subtask H12_4_1 = Subtask.builder() + .description("H12.4.1 | Huffman-Komprimierung") + .testClassName("h12.H12_4_1_Tests") + .criterion("Die Methode getText() liest den Text korrekt ein.", "testGetText", JsonParameterSet.class) + .criterion("Die Methode computeTextSize(String text, EncodingTable encodingTable) berechnet die Anzahl an Bits, die für die Komprimierung des Textes nötig ist, korrekt.", "testComputeTextSize", JsonParameterSet.class) + .criterion("Die Methode encodeText(String text, EncodingTable encodingTable) komprimiert den Text korrekt.", "testEncodeText", JsonParameterSet.class) + .criterion("Die Methode compress() ist vollständig und korrekt.", "testCompress", JsonParameterSet.class) + .build(); + + /** + * Defines the subtask H12.4.2 for task H12.2. + */ + private static final Subtask H12_4_2 = Subtask.builder() + .description("H12.4.2 | Huffman-Dekomprimierung") + .testClassName("h12.H12_4_2_Tests") + .criterion("Die Methode skipBits() überspringt die Füllbits korrekt.", false, "testSkipBits", JsonParameterSet.class) + .criterion("Die Methode decodeCharacter(int startBit, EncodingTable encodingTable) dekomprimiert einen Zeichen korrekt.", false, "testDecodeCharacter", JsonParameterSet.class) + .criterion("Die Methode decodeText(EncodingTable encodingTable) Dekomprimiert den Text korrekt.", false, "testDecodeText", JsonParameterSet.class) + .criterion("Die Methode decompress() ist vollständig und korrekt.", false, "testDecompress", JsonParameterSet.class) + .build(); + + /** + * Defines the task H12.4. + */ + private static final Task H12_4 = Task.builder() + .description("H12.4 | Die Kunst des Codes: Huffman-Coding II") + .subtasks(H12_4_1, H12_4_2) + .build(); + + /** + * Whether the private tests are being graded. + */ + private final boolean publicTests; + + /** + * Constructs a new rubric provider. + * + * @param publicTests whether the private tests are being graded + */ + public H12_RubricProvider(boolean publicTests) { + this.publicTests = publicTests; + } + + /** + * Constructs a new public rubric provider. + */ + public H12_RubricProvider() { + this(true); + } + + @Override + public Rubric getRubric() { + return Rubric.builder() + .title("H12 | Datenkomprimierung - %s Tests".formatted(publicTests ? "Public" : "Private")) + .addChildCriteria( + Stream.of(H12_1, H12_2, H12_3, H12_4) + .map(Task::getCriterion) + .toArray(Criterion[]::new) + ).build(); + } +} diff --git a/solution/H12/src/graderPublic/java/h12/rubric/Subtask.java b/solution/H12/src/graderPublic/java/h12/rubric/Subtask.java new file mode 100644 index 0000000..29086c9 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/rubric/Subtask.java @@ -0,0 +1,324 @@ +package h12.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; +import org.sourcegrade.jagr.api.rubric.Gradable; +import org.sourcegrade.jagr.api.rubric.Grader; +import org.sourcegrade.jagr.api.rubric.JUnitTestRef; +import org.tudalgo.algoutils.tutor.general.jagr.RubricUtils; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Stream; + +/** + * Represents a subtask in a rubric. + * + * @param description a short description of the subtask + * @param criteria the subtasks that must be met to complete the subtask + * @param requirements the requirements that must be met to complete the subtask + * + * @author Nhan Huynh + */ +public record Subtask( + String description, + List criteria, + List requirements +) implements Criteriable { + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + * + * @return a new subtask builder + */ + public static SubtaskBuilder builder() { + return new SubtaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .minPoints(0) + .addChildCriteria(Stream.concat(criteria.stream(), requirements.stream()).toArray(Criterion[]::new)) + .build(); + } + + /** + * Returns a new {@link SubtaskBuilder} to build a {@link Subtask}. + */ + public interface SubtaskBuilder extends Builder { + + /** + * Sets the description of the subtask. + * + * @param description the description of the subtask + * + * @return this builder instance with the description set + */ + SubtaskBuilder description(String description); + + /** + * Sets the name of the test class that tests this subtask. + * + * @param testClassName the name of the test class that tests this subtask + * + * @return this builder instance with the test class name set + */ + SubtaskBuilder testClassName(String testClassName); + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the criterion added + */ + SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ); + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, Map>> testMethodsSignature) { + return criterion(description, true, testMethodsSignature); + } + + /** + * Adds a criterion to the subtask. + * + * @param description the description of the criterion + * @param publicTest whether the test is public + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion( + String description, + boolean publicTest, + String testMethodName, + Class... testMethodParameters + ) { + return criterion(description, publicTest, Map.of(testMethodName, List.of(testMethodParameters))); + } + + /** + * Adds a public criterion to the subtask. + * + * @param description the description of the criterion + * @param testMethodName the name of the test method + * @param testMethodSignature the signature of the test method + * + * @return this builder instance with the criterion added + */ + default SubtaskBuilder criterion(String description, String testMethodName, Class... testMethodSignature) { + return criterion(description, true, testMethodName, testMethodSignature); + } + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodsSignature the signature of the test methods + * + * @return this builder instance with the requirement added + */ + SubtaskBuilder requirement(String description, Map>> testMethodsSignature); + + /** + * Adds a requirement to the subtask. + * + * @param description the description of the requirement + * @param testMethodName the name of the test method + * @param testMethodParameters the parameters of the test method + * + * @return this builder instance with the requirement added + */ + default SubtaskBuilder requirement(String description, String testMethodName, Class... testMethodParameters) { + return requirement(description, Map.of(testMethodName, List.of(testMethodParameters))); + } + } + + /** + * A builder for building {@link Subtask} instances. + */ + private static class SubtaskCriteriaBuilderImpl implements SubtaskBuilder { + + /** + * The description of the subtask. + */ + private @NotNull String description = ""; + + /** + * The name of the test class that tests this subtask. + */ + private @NotNull String testClassName = ""; + + /** + * The subtasks of the subtask. + */ + private final List> criteria = new ArrayList<>(); + + /** + * The requirements of the subtask. + */ + private final List> requirements = new ArrayList<>(); + + @Override + public SubtaskBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public SubtaskBuilder testClassName(String testClassName) { + this.testClassName = testClassName; + return this; + } + + /** + * Returns the description of the subtask. + * + * @return the description of the subtask + */ + private @NotNull String getDescription() { + return description; + } + + /** + * Returns a pre-configured criterion builder where the description and grader are set. + * + * @param description the description of the criterion + * @param grader the grader of the criterion + * + * @return a pre-configured criterion builder with the description and grader set + */ + private Criterion.Builder criterionBuilder(String description, Grader grader) { + return Criterion.builder() + .shortDescription(description) + .grader(grader); + } + + /** + * Returns a pre-configured criterion builder where the description and test reference are set. + * + * @param description the description of the criterion + * @param testRef the test reference of the criterion + * + * @return a pre-configured criterion builder with the description and test reference set + */ + private Criterion.Builder criterionBuilder(String description, JUnitTestRef testRef) { + return criterionBuilder( + description, + Grader.testAwareBuilder() + .requirePass(testRef) + .pointsFailedMin() + .pointsPassedMax() + .build() + ); + } + + /** + * Creates a criterion supplier with the given description, class name, test methods signature, and points. + * Since the points can only be determined after all subtasks are added, the points are calculated lazily. + * + * @param description the description of the criterion + * @param className the name of the test class that tests this subtask + * @param testMethodsSignature the signature of the test methods + * @param points the points of the criterion + * + * @return a criterion supplier with the given description, class name, test methods signature, and points + */ + private Supplier criterion( + String description, + String className, + Map>> testMethodsSignature, + Supplier points + ) { + return () -> { + Criterion.Builder builder; + try { + List testRefs = new ArrayList<>(testMethodsSignature.size()); + for (Map.Entry>> entry : testMethodsSignature.entrySet()) { + Method method = Class.forName(className).getDeclaredMethod( + entry.getKey(), + entry.getValue().toArray(Class[]::new) + ); + testRefs.add(JUnitTestRef.ofMethod(method)); + } + builder = criterionBuilder(description, JUnitTestRef.and(testRefs.toArray(JUnitTestRef[]::new))); + } catch (Exception e) { + builder = criterionBuilder(description, RubricUtils.graderPrivateOnly()); + } + int pointsValue = points.get(); + if (pointsValue >= 0) { + builder.minPoints(0); + builder.maxPoints(pointsValue); + } else { + builder.maxPoints(0); + builder.minPoints(pointsValue); + } + return builder.build(); + }; + } + + @Override + public SubtaskBuilder criterion( + String description, + boolean publicTest, + Map>> testMethodsSignature + ) { + criteria.add( + criterion( + description, + testClassName + (publicTest ? "Public" : "Private"), + testMethodsSignature, + () -> 1 + ) + ); + return this; + } + + @Override + public SubtaskBuilder requirement(String description, Map>> testMethodsSignature) { + requirements.add( + criterion( + description, + testClassName + "Private", + testMethodsSignature, + () -> -criteria.stream() + .map(Supplier::get) + .mapToInt(Gradable::getMaxPoints) + .sum() + ) + ); + return this; + } + + @Override + public Subtask build() { + if (testClassName.isBlank()) { + throw new IllegalStateException("Test class name cannot be blank!"); + } + return new Subtask( + description, + criteria.stream().map(Supplier::get).toList(), + requirements.stream().map(Supplier::get).toList() + ); + } + } +} diff --git a/solution/H12/src/graderPublic/java/h12/rubric/Task.java b/solution/H12/src/graderPublic/java/h12/rubric/Task.java new file mode 100644 index 0000000..33c2022 --- /dev/null +++ b/solution/H12/src/graderPublic/java/h12/rubric/Task.java @@ -0,0 +1,106 @@ +package h12.rubric; + +import org.jetbrains.annotations.NotNull; +import org.sourcegrade.jagr.api.rubric.Criterion; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a task in a rubric. + * + * @param description a short description of the task + * @param subtasks the subtasks that must be met to complete the task + * + * @author Nhan Huynh + */ +public record Task(String description, List subtasks) implements Criteriable { + + /** + * Returns a new {@link TaskCriteriaBuilder} to build a {@link Task}. + * + * @return a new task subtasks builder + */ + public static TaskCriteriaBuilder builder() { + return new TaskCriteriaBuilderImpl(); + } + + @Override + public Criterion getCriterion() { + return Criterion.builder() + .shortDescription(description) + .addChildCriteria(subtasks.stream().map(Subtask::getCriterion).toArray(Criterion[]::new)) + .build(); + } + + /** + * + */ + public interface TaskCriteriaBuilder extends Builder { + + /** + * Sets the description of the task. + * + * @param description the description of the task + * + * @return this builder instance with the description set + */ + TaskCriteriaBuilder description(String description); + + /** + * Adds subtasks to the task. + * + * @param subtasks the subtasks to add + * + * @return this builder instance with the subtasks added + */ + TaskCriteriaBuilder subtasks(Subtask... subtasks); + + /** + * Adds a criterion to the task. + * + * @param criterion the criterion to add + * + * @return this builder instance with the criterion added + */ + default TaskCriteriaBuilder subtask(Subtask criterion) { + return subtasks(criterion); + } + } + + /** + * A builder for building {@link Task} instances. + */ + private static class TaskCriteriaBuilderImpl implements TaskCriteriaBuilder { + + /** + * The description of the task. + */ + private @NotNull String description = ""; + + /** + * The subtasks of the task. + */ + private final List criteria = new ArrayList<>(); + + @Override + public TaskCriteriaBuilder description(@NotNull String description) { + this.description = description; + return this; + } + + @Override + public TaskCriteriaBuilder subtasks(Subtask... subtasks) { + this.criteria.addAll(List.of(subtasks)); + return this; + } + + @Override + public Task build() { + if (description.isBlank()) { + throw new IllegalArgumentException("Description cannot be blank!"); + } + return new Task(description, criteria); + } + } +} diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json new file mode 100644 index 0000000..ab3e53b --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchEOF.json @@ -0,0 +1,12 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json new file mode 100644 index 0000000..7ab7cc0 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testFetchNotEOF.json @@ -0,0 +1,36 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1 + ], + "bufferPostState": 215, + "positionPostState": 7 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json new file mode 100644 index 0000000..be4ca2f --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testRead.json @@ -0,0 +1,115 @@ +[ + { + "bitsPreState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": 7, + "bitsPostState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPostState": 69, + "positionPostState": -1, + "expectedByte": 69 + }, + { + "bitsPreState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": 3, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPostState": 178, + "positionPostState": 0, + "expectedByte": 91 + }, + { + "bitsPreState": [ + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPreState": 69, + "positionPreState": 0, + "bitsPostState": [ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1 + ], + "bufferPostState": 178, + "positionPostState": 0, + "expectedByte": 217 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json new file mode 100644 index 0000000..2e06ff4 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferEnd.json @@ -0,0 +1,45 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": 69, + "positionPostState": -1, + "expectedBit": 1 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json new file mode 100644 index 0000000..0e57973 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferMiddle.json @@ -0,0 +1,45 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": 3, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": 69, + "positionPostState": 2, + "expectedBit": 0 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json new file mode 100644 index 0000000..7a1e456 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitBufferStart.json @@ -0,0 +1,45 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": 7, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": 69, + "positionPostState": 6, + "expectedBit": 0 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json new file mode 100644 index 0000000..6d70391 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitEOF.json @@ -0,0 +1,13 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1, + "expectedBit": -1 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json new file mode 100644 index 0000000..814894d --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadBitNextByte.json @@ -0,0 +1,72 @@ +[ + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": null, + "positionPostState": 7, + "expectedBit": 1 + }, + { + "bitsPreState": [ + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0 + ], + "bufferPostState": null, + "positionPostState": 7, + "expectedBit": 0 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json new file mode 100644 index 0000000..b801b91 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadEnd.json @@ -0,0 +1,13 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": -1, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1, + "expectedByte": -1 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json new file mode 100644 index 0000000..62cc217 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_1_testReadPartial.json @@ -0,0 +1,13 @@ +[ + { + "bitsPreState": [ + ], + "bufferPreState": 69, + "positionPreState": 3, + "bitsPostState": [ + ], + "bufferPostState": null, + "positionPostState": -1, + "expectedByte": 80 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json b/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json new file mode 100644 index 0000000..e6fb409 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testCompress.json @@ -0,0 +1,349 @@ +[ + { + "bitsPreState": [ + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [], + "counts": [], + "compressedBits": [] + }, + { + "bitsPreState": [ + 0 + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [ + 0 + ], + "counts": [ + 1 + ], + "compressedBits": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "bitsPreState": [ + 1 + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [ + 1 + ], + "counts": [ + 1 + ], + "compressedBits": [ + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + }, + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": -1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "startBits": [ + 0, + 1, + 0, + 0, + 1 + ], + "counts": [ + 5, + 1, + 127, + 62, + 26 + ], + "compressedBits": [ + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0 + ] + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json b/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json new file mode 100644 index 0000000..660199b --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountMax.json @@ -0,0 +1,560 @@ +[ + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPostState": 0, + "bit": 0, + "count": 127 + }, + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPreState": 1, + "bitsPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPostState": 1, + "bit": 1, + "count": 127 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json b/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json new file mode 100644 index 0000000..45adea2 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_1_Tests_testGetBitCountNotMax.json @@ -0,0 +1,516 @@ +[ + { + "bitsPreState": [ + ], + "lastReadPreState": 0, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "bit": 0, + "count": 1 + }, + { + "bitsPreState": [ + ], + "lastReadPreState": 1, + "bitsPostState": [ + ], + "lastReadPostState": -1, + "bit": 1, + "count": 1 + }, + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPostState": 1, + "bit": 0, + "count": 126 + }, + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPreState": 1, + "bitsPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPostState": 0, + "bit": 1, + "count": 126 + }, + { + "bitsPreState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPreState": 0, + "bitsPostState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + "lastReadPostState": 1, + "bit": 0, + "count": 71 + }, + { + "bitsPreState": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPreState": 1, + "bitsPostState": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "lastReadPostState": 0, + "bit": 1, + "count": 71 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json b/solution/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json new file mode 100644 index 0000000..0dbb4e6 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_3_2_Tests_testRemoveMin.json @@ -0,0 +1,118 @@ +[ + { + "elementsPreState": [ + 1 + ], + "elementsPostState": [ + ], + "minimumElement": 1 + }, + { + "elementsPreState": [ + 2, + 3 + ], + "elementsPostState": [ + 3 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 2, + 1 + ], + "elementsPostState": [ + 2 + ], + "minimumElement": 1 + }, + { + "elementsPreState": [ + 2, + 4, + 3, + 7, + 2, + 6, + 54 + ], + "elementsPostState": [ + 4, + 3, + 7, + 2, + 6, + 54 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 4, + 3, + 7, + 2, + 6, + 54, + 2 + ], + "elementsPostState": [ + 4, + 3, + 7, + 6, + 54, + 2 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 5, + 3, + 7, + 2, + 6, + 54, + 2 + ], + "elementsPostState": [ + 5, + 3, + 7, + 6, + 54, + 2 + ], + "minimumElement": 2 + }, + { + "elementsPreState": [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ], + "elementsPostState": [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ], + "minimumElement": 2 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json new file mode 100644 index 0000000..01cb9ec --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testCompress.json @@ -0,0 +1,17458 @@ +[ + { + "text": "H", + "encodingTable": { + "H": "1" + }, + "compressed": [ + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1 + ] + }, + { + "text": "Hello, World!", + "encodingTable": { + " ": "1010", + "!": "1011", + "r": "1100", + "d": "1101", + "e": "1110", + "W": "1111", + "H": "000", + ",": "001", + "l": "01", + "o": "100" + }, + "compressed": [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1 + ] + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "compressed": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json new file mode 100644 index 0000000..19b910d --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testComputeTextSize.json @@ -0,0 +1,79 @@ +[ + { + "text": "H", + "encodingTable": { + "H": "1" + }, + "textSize": 1 + }, + { + "text": "Hello, World!", + "encodingTable": { + " ": "1010", + "!": "1011", + "r": "1100", + "d": "1101", + "e": "1110", + "W": "1111", + "H": "000", + ",": "001", + "l": "01", + "o": "100" + }, + "textSize": 42 + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "textSize": 15297 + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json new file mode 100644 index 0000000..5f87588 --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testEncodeText.json @@ -0,0 +1,15422 @@ +[ + { + "text": "H", + "encodingTable": { + "H": "1" + }, + "compressed": [ + 1 + ] + }, + { + "text": "Hello, World!", + "encodingTable": { + " ": "1010", + "!": "1011", + "r": "1100", + "d": "1101", + "e": "1110", + "W": "1111", + "H": "000", + ",": "001", + "l": "01", + "o": "100" + }, + "compressed": [ + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1 + ] + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh.", + "encodingTable": { + "A": "00101011", + "B": "111001100110", + "C": "0011010101", + "D": "0011011111", + "E": "111001100111", + "F": "00110101000", + "G": "00110101001", + "H": "0011011010", + "I": "001101011", + "\n": "11100111", + "L": "0011011011", + "M": "001010010", + "N": "1110011000", + "O": "001101100", + "P": "00110111101", + "R": "0011011100", + "S": "111001101", + "T": "11100110010", + "U": "0011011101", + "W": "001010011", + "Y": "00110111100", + " ": "110", + "a": "0000", + "b": "001100", + "c": "111111", + "d": "11101", + "e": "011", + "f": "101001", + "g": "101000", + "h": "111110", + "i": "1001", + "j": "001010100", + "k": "00101000", + "l": "10101", + "m": "00111", + "n": "1011", + ".": "111100", + "o": "1000", + "p": "111000", + "q": "001010101", + "r": "0001", + "s": "0100", + "t": "0101", + "u": "00100", + "v": "1110010", + "w": "001011", + "x": "00110100", + "y": "111101" + }, + "compressed": [ + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 1, + 1, + 0, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 1, + 0, + 1, + 1, + 1, + 0, + 0, + 1, + 1, + 0, + 1, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 0, + 0 + ] + } +] diff --git a/solution/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json new file mode 100644 index 0000000..a81453a --- /dev/null +++ b/solution/H12/src/graderPublic/resources/h12/H12_4_1_testGetText.json @@ -0,0 +1,17 @@ +[ + { + "text": "" + }, + { + "text": "H" + }, + { + "text": "Hello, World!" + }, + { + "text": "Offered say visited elderly and. Waited period are played family man formed. He ye body or made on pain part meet. You one delay nor begin our folly abode. By disposed replying mr me unpacked no. As moonlight of my resolving unwilling.\n\nSupported neglected met she therefore unwilling discovery remainder. Way sentiments two indulgence uncommonly own. Diminution to frequently sentiments he connection continuing indulgence. An my exquisite conveying up defective. Shameless see the tolerably how continued. She enable men twenty elinor points appear. Whose merry ten yet was men seven ought balls.\n\nMonths on ye at by esteem desire warmth former. Sure that that way gave any fond now. His boy middleton sir nor engrossed affection excellent. Dissimilar compliment cultivated preference eat sufficient may. Well next door soon we mr he four. Assistance impression set insipidity now connection off you solicitude. Under as seems we me stuff those style at. Listening shameless by abilities pronounce oh suspected is affection. Next it draw in draw much bred.\n\nRank tall boy man them over post now. Off into she bed long fat room. Recommend existence curiosity perfectly favourite get eat she why daughters. Not may too nay busy last song must sell. An newspaper assurance discourse ye certainly. Soon gone game and why many calm have.\n\nOn then sake home is am leaf. Of suspicion do departure at extremely he believing. Do know said mind do rent they oh hope of. General enquire picture letters garrets on offices of no on. Say one hearing between excited evening all inhabit thought you. Style begin mr heard by in music tried do. To unreserved projection no introduced invitation.\n\nCan curiosity may end shameless explained. True high on said mr on come. An do mr design at little myself wholly entire though. Attended of on stronger or mr pleasure. Rich four like real yet west get. Felicity in dwelling to drawings. His pleasure new steepest for reserved formerly disposed jennings.\n\nAt as in understood an remarkably solicitude. Mean them very seen she she. Use totally written the observe pressed justice. Instantly cordially far intention recommend estimable yet her his. Ladies stairs enough esteem add fat all enable. Needed its design number winter see. Oh be me sure wise sons no. Piqued ye of am spirit regret. Stimulated discretion impossible admiration in particular conviction up.\n\nUnpacked now declared put you confined daughter improved. Celebrated imprudence few interested especially reasonable off one. Wonder bed elinor family secure met. It want gave west into high no in. Depend repair met before man admire see and. An he observe be it covered delight hastily message. Margaret no ladyship endeavor ye to settling.\n\nOut too the been like hard off. Improve enquire welcome own beloved matters her. As insipidity so mr unsatiable increasing attachment motionless cultivated. Addition mr husbands unpacked occasion he oh. Is unsatiable if projecting boisterous insensible. It recommend be resolving pretended middleton.\n\nAsk especially collecting terminated may son expression. Extremely eagerness principle estimable own was man. Men received far his dashwood subjects new. My sufficient surrounded an companions dispatched in on. Connection too unaffected expression led son possession. New smiling friends and her another. Leaf she does none love high yet. Snug love will up bore as be. Pursuit man son musical general pointed. It surprise informed mr advanced do outweigh." + }, + { + "text": "Habs bi dies en satz. Oha was gefallt woruber erzahlt das stellte steigst tat glatten. Ige der kraftiger schneider plaudernd vom schonsten. Es du kenne vater stuck. Namlich abwarts gut mundart gab tur nur. Viele du immer szene leise kaute so.\n\nGar meisterin ihn arbeitete uhr ernsthaft. Im bewirtung da gestorben du zerfasert verodeten. Frohlich ist schuftet hinabsah begierig gar dus ihr. Stimmts weg gedacht glatten zum weibern ort ist. Hande sehet kennt te da lauft. Ichs in welt pa eile hing. Ei betrubte da wo geworden launisch ehrbaren madchens.\n\nZu ku auskleiden aufzulosen dazwischen. Lockere ich grausam mundart hochmut ein fenster. Du aufraumen lieblinge geblendet vergesset zu. Mit bettstatt gib schneider hemdarmel unterwegs war. Sog klein das sagen kalte leise vom zwirn licht. Hellen verlie uhr kommen jungen bis freute eck schade gut. Samstag konnten gefreut nun zuliebe vor lichten.\n\nBat ist landsleute hin nachmittag vorpfeifen. Pa es klopfte an flecken wu tadelte. Darauf dus neckte hin als gebaut lag. Kindliche weiterhin mannsbild ob zu windstill. Herr gast sei gut ists. Hufschmied bat ehe wei scherzwort drechslers grundstuck wohlgefuhl man aufgespart. Gehe se luke ruth weil en ei wege. Schen kennt nobel sie gut wie und schau dafur.\n\nSo zaunpfahle mi neidgefuhl em vertreiben wo gesprachig angenommen. Du em paar muhe in so doch. In es frauen te kunste kurios zu. Ist denen leise weich nacht aller eia man steht ich. Losen es ewige zu nicht leben. Hinabsah leichter tadellos mehrmals im ziemlich la em wo.\n\nSa gelernte he am uberging verwohnt. Liebhaben mudigkeit gestrigen nie kam wie tanzmusik ausdenken. An wo du gerbers gelehnt so schritt. Musset mochte du gesund es la sprach seinen. Ubel all tat gelt eine sie tor lied. Verschwand hoffnungen todesfalle er ri an da nettigkeit. Geworden in schonste familien launigen nirgends mi.\n\nIhr grasgarten aus gab ich vorpfeifen nettigkeit bodenlosen. Es ziegen jawohl freude bi fraget bugeln. Em tage te bett arme. Er heran ab so hinab damit rasch. Luften verlie zopfen dir nur. Warf geh alle beim frau den. So heiraten zu konntest fraulein schweren la. Dem beneidest tanzmusik ehe ausdenken gegriffen kraftiger arbeitete gro. Hufschmied verbergend em am sa aufzulosen. Redete luftig klaren fur nur strich stimme ers nur.\n\nVor zog was will ehre paar des. Meinung gelernt scheint flo gefreut manchen das. Es lehrlingen da in nachtessen geschwatzt erhaltenen sonderling schuchtern. Nirgends mi gespielt zugvogel weiblein er em. Ja werkstatte an bescheiden hufschmied neidgefuhl. Ei handwerke en ernstlich kammertur barbieren.\n\nPa wohnstube er kindliche ri schonheit da. Befangenen ihr fluchtigen die lag dachkammer mit. Funfe an schlo enden ja dabei zu es licht. Nichtstun nachgehen im wo lohgruben. Vom ausdenken ist hei filzhutes leuchtete hochstens. Um gern hing so laut da hast.\n\nGesehen konnten in wu dunklem schaute. Einige je wo en in groben besann spater verlor. Schuchtern geheiratet in verrichtet pa bodenlosen betrachtet se am vorpfeifen. Kleine grunde ja da luften werden reihen. Ahren alten enden wo sunde in immer du. Wahrend wie ein nur bereits gewogen niemand man. Froh du voll hing im kerl in euch funf zu. Gebogene ort brauchte uberlegt gut." + } +] diff --git a/solution/H12/src/main b/solution/H12/src/main new file mode 120000 index 0000000..22eee3e --- /dev/null +++ b/solution/H12/src/main @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H12/src/main \ No newline at end of file diff --git a/solution/H12/src/test b/solution/H12/src/test new file mode 120000 index 0000000..a1eb1bf --- /dev/null +++ b/solution/H12/src/test @@ -0,0 +1 @@ +/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H12/src/test \ No newline at end of file diff --git a/solution/H12/version b/solution/H12/version new file mode 100644 index 0000000..b694fe3 --- /dev/null +++ b/solution/H12/version @@ -0,0 +1 @@ +0.1.0-SNAPSHOT