├── .gitignore ├── Appium ├── GeekNews │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── GuDong │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── JDmall │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── Leafpicv31 │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── Leafpicv6 │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── Meituan │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── Smzdm │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java ├── Zhwnl │ └── src │ │ └── com │ │ └── mooctest │ │ └── Main.java └── Zykq │ └── src │ └── com │ └── mooctest │ └── Main.java ├── JUnit ├── ALU │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── mooctest │ │ │ └── ALU.java │ │ └── test │ │ └── java │ │ └── net │ │ └── mooctest │ │ └── ALUTest.java ├── Anagram │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── mooctest │ │ │ │ ├── Anagram.java │ │ │ │ ├── Dictionary.java │ │ │ │ └── Helper.java │ │ └── resources │ │ │ └── net │ │ │ └── mooctest │ │ │ └── demo.txt │ │ └── test │ │ └── java │ │ └── net │ │ └── mooctest │ │ ├── AnagramTest.java │ │ ├── DictionaryTest.java │ │ └── HelperTest.java ├── ArgsParser │ ├── src │ │ ├── ArgsParser.java │ │ ├── Argument.java │ │ ├── KeyArgument.java │ │ ├── ParameterArgument.java │ │ ├── StringArgument.java │ │ └── SwitchArgument.java │ └── test │ │ └── ArgsParserTest.java ├── BPlusTree │ ├── src │ │ ├── BPlusTree.java │ │ ├── InsertionResult.java │ │ ├── IntegerBloomFilter.java │ │ ├── InternalNode.java │ │ ├── LeafNode.java │ │ └── Node.java │ └── test │ │ ├── BPlusTreeTest.java │ │ ├── BPlusTree_ESTest.java │ │ ├── InsertionResult_ESTest.java │ │ ├── IntegerBloomFilter_ESTest.java │ │ ├── InternalNode_ESTest.java │ │ ├── LeafNode_ESTest.java │ │ └── Node_ESTest.java ├── Brainfuck │ └── src │ │ ├── main │ │ ├── java │ │ │ └── net │ │ │ │ └── mooctest │ │ │ │ ├── BrainfuckEngine.java │ │ │ │ ├── OokEngine.java │ │ │ │ └── TrollScriptEngine.java │ │ └── resources │ │ │ └── net │ │ │ └── mooctest │ │ │ └── demo.txt │ │ └── test │ │ └── java │ │ └── net │ │ └── mooctest │ │ ├── BrainfuckEngineTest.java │ │ ├── OokEngineTest.java │ │ └── TrollScriptEngineTest.java ├── CMD │ ├── src │ │ └── CMD.java │ └── test │ │ └── CMDTest.java ├── ITClocks │ ├── src │ │ ├── Event.java │ │ ├── Events.java │ │ ├── Filler.java │ │ ├── GrowResult.java │ │ ├── Grower.java │ │ ├── ID.java │ │ ├── IDs.java │ │ ├── ITClocks.java │ │ ├── LeafEvent.java │ │ ├── LeafID.java │ │ ├── NonLeafEvent.java │ │ ├── NonLeafID.java │ │ └── Stamp.java │ └── test │ │ ├── FillerTest.java │ │ ├── GrowerTest.java │ │ ├── IDsTest.java │ │ ├── ITClocksTest.java │ │ ├── LeafEventTest.java │ │ ├── LeafIDTest.java │ │ ├── NonLeafEventTest.java │ │ ├── NonLeafIDTest.java │ │ └── StampTest.java ├── JCLO │ ├── src │ │ └── JCLO.java │ └── test │ │ └── JCLOTest.java ├── MSD │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── mooctest │ │ │ └── MSD.java │ │ └── test │ │ └── java │ │ └── net │ │ └── mooctest │ │ └── MSDTest.java ├── MatrixInverse │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── mooctest │ │ │ └── MatrixInverse.java │ │ └── test │ │ └── java │ │ └── net │ │ └── mooctest │ │ └── MatrixInverseTest.java ├── Nextday │ ├── src │ │ ├── CalendarUnit.java │ │ ├── Date.java │ │ ├── Day.java │ │ ├── Month.java │ │ ├── Nextday.java │ │ └── Year.java │ └── test │ │ └── NextdayTest.java ├── RedBlackTree │ └── src │ │ ├── main │ │ └── java │ │ │ └── net │ │ │ └── mooctest │ │ │ ├── AbstractBinaryTree.java │ │ │ ├── Node.java │ │ │ └── RedBlackTree.java │ │ └── test │ │ └── java │ │ └── net │ │ └── mooctest │ │ └── RedBlackTreeTest.java └── SuffixArray │ ├── src │ └── SuffixArray.java │ └── test │ └── SuffixArrayTest.java └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /Appium/GeekNews/src/com/mooctest/Main.java: -------------------------------------------------------------------------------- 1 | package com.mooctest; 2 | 3 | import io.appium.java_client.AndroidKeyCode; 4 | import io.appium.java_client.AppiumDriver; 5 | import org.openqa.selenium.remote.DesiredCapabilities; 6 | 7 | import java.io.File; 8 | import java.net.MalformedURLException; 9 | import java.net.URL; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | 13 | public class Main { 14 | 15 | /** 16 | * 所有和AppiumDriver相关的操作都必须写在该函数中 17 | * 18 | * @param driver 19 | */ 20 | public void test(AppiumDriver driver) { 21 | driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS); //设置尝试定位控件的最长时间为8s,也就是最多尝试8s 22 | /* 23 | * 余下的测试逻辑请按照题目要求进行编写 24 | */ 25 | 26 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='打开']").click(); 27 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='知乎日报']").click(); 28 | driver.findElementByXPath("//android.widget.TextView[@text='日报']").click(); 29 | driver.findElementById("com.codeest.geeknews:id/fab_calender").click(); 30 | driver.findElementById("com.codeest.geeknews:id/tv_calender_enter").click(); 31 | driver.findElementById("com.codeest.geeknews:id/iv_top_image").click(); 32 | driver.findElementById("com.codeest.geeknews:id/fab_like").click(); 33 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 34 | 35 | driver.findElementByXPath("//android.widget.TextView[@text='主题']").click(); 36 | driver.findElementByXPath("//android.widget.TextView[@text='日常心理学']").click(); 37 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 38 | 39 | driver.findElementByXPath("//android.widget.TextView[@text='专栏']").click(); 40 | driver.findElementByXPath("//android.widget.TextView[@text='深夜惊奇']").click(); 41 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 42 | 43 | driver.findElementByXPath("//android.widget.TextView[@text='热门']").click(); 44 | 45 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='打开']").click(); 46 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='微信精选']").click(); 47 | driver.findElementById("com.codeest.geeknews:id/action_search").click(); 48 | driver.findElementById("com.codeest.geeknews:id/action_up_btn").click(); 49 | driver.findElementById("com.codeest.geeknews:id/action_search").click(); 50 | driver.findElementById("com.codeest.geeknews:id/searchTextView").sendKeys("测试"); 51 | driver.sendKeyEvent(AndroidKeyCode.ENTER); 52 | driver.findElementsById("com.codeest.geeknews:id/tv_wechat_item_title").get(0).click(); 53 | driver.findElementById("com.codeest.geeknews:id/action_like").click(); 54 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 55 | driver.findElementByXPath("//android.widget.TextView[@text='复制链接到剪贴板']").click(); 56 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 57 | driver.findElementByXPath("//android.widget.TextView[@text='分享链接']").click(); 58 | driver.sendKeyEvent(AndroidKeyCode.BACK); 59 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 60 | 61 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='打开']").click(); 62 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='干货集中营']").click(); 63 | driver.findElementByXPath("//android.widget.TextView[@text='ANDROID']").click(); 64 | driver.findElementByXPath("//android.widget.TextView[@text='IOS']").click(); 65 | driver.findElementByXPath("//android.widget.TextView[@text='前端']").click(); 66 | driver.findElementByXPath("//android.widget.TextView[@text='福利']").click(); 67 | 68 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='打开']").click(); 69 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='收藏']").click(); 70 | 71 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='打开']").click(); 72 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='设置']").click(); 73 | driver.findElementById("com.codeest.geeknews:id/cb_setting_cache").click(); 74 | driver.findElementById("com.codeest.geeknews:id/cb_setting_image").click(); 75 | driver.findElementById("com.codeest.geeknews:id/cb_setting_night").click(); 76 | driver.findElementByXPath("//android.widget.TextView[@text='意见反馈']").click(); 77 | driver.sendKeyEvent(AndroidKeyCode.BACK); 78 | driver.findElementByXPath("//android.widget.TextView[@text='清除缓存']").click(); 79 | driver.findElementByXPath("//android.widget.TextView[@text='检查更新']").click(); 80 | 81 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='打开']").click(); 82 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='关于']").click(); 83 | } 84 | 85 | private void waitForActivity(AppiumDriver driver, String activity) { 86 | activity = "." + activity; 87 | while (!driver.currentActivity().contains(activity)) { 88 | System.out.println("- Waiting for " + activity); 89 | Thread.yield(); 90 | } 91 | System.out.println(">> Begin " + activity); 92 | } 93 | 94 | /** 95 | * AppiumDriver的初始化逻辑必须写在该函数中 96 | * 97 | * @return 98 | */ 99 | public AppiumDriver initAppiumTest() { 100 | 101 | AppiumDriver driver = null; 102 | File classpathRoot = new File(System.getProperty("user.dir")); 103 | File appDir = new File(classpathRoot, "apk"); 104 | File app = new File(appDir, "GeekNews.apk"); 105 | 106 | //设置自动化相关参数 107 | DesiredCapabilities capabilities = new DesiredCapabilities(); 108 | capabilities.setCapability("automationName", "UiAutomator2"); 109 | capabilities.setCapability("browserName", ""); 110 | capabilities.setCapability("platformName", "Android"); 111 | capabilities.setCapability("deviceName", "Android Emulator"); 112 | capabilities.setCapability("appPackage", "com.codeest.geeknews"); 113 | capabilities.setCapability("appActivity", "com.codeest.geeknews.ui.main.activity.WelcomeActivity"); 114 | capabilities.setCapability("noSign", "true"); 115 | 116 | //设置apk路径 117 | capabilities.setCapability("app", app.getAbsolutePath()); 118 | 119 | //设置使用unicode键盘,支持输入中文和特殊字符 120 | capabilities.setCapability("unicodeKeyboard", "true"); 121 | //设置用例执行完成后重置键盘 122 | capabilities.setCapability("resetKeyboard", "true"); 123 | //初始化 124 | try { 125 | driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 126 | } catch (MalformedURLException e) { 127 | // TODO Auto-generated catch block 128 | e.printStackTrace(); 129 | } 130 | return driver; 131 | } 132 | 133 | public void start() { 134 | test(initAppiumTest()); 135 | } 136 | 137 | public static void main(String[] args) { 138 | Main main = new Main(); 139 | main.start(); 140 | } 141 | 142 | 143 | } -------------------------------------------------------------------------------- /Appium/GuDong/src/com/mooctest/Main.java: -------------------------------------------------------------------------------- 1 | package com.mooctest; 2 | 3 | import io.appium.java_client.AndroidKeyCode; 4 | import io.appium.java_client.AppiumDriver; 5 | import org.openqa.selenium.remote.DesiredCapabilities; 6 | 7 | import java.io.File; 8 | import java.net.MalformedURLException; 9 | import java.net.URL; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | 13 | public class Main { 14 | 15 | /** 16 | * 所有和AppiumDriver相关的操作都必须写在该函数中 17 | * 18 | * @param driver 19 | */ 20 | public void test(AppiumDriver driver) { 21 | driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS); //设置尝试定位控件的最长时间为8s,也就是最多尝试8s 22 | /* 23 | * 余下的测试逻辑请按照题目要求进行编写 24 | */ 25 | 26 | driver.findElementByXPath("//android.widget.Button[@text='确定']").click(); 27 | driver.findElementByXPath("//android.widget.Button[@text='取消']").click(); 28 | 29 | driver.findElementById("name.gudong.translate:id/menu_book").click(); 30 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 31 | waitForActivity(driver, "MainActivity"); 32 | 33 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 34 | driver.findElementByXPath("//android.widget.TextView[@text='历史记录']").click(); 35 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 36 | waitForActivity(driver, "MainActivity"); 37 | 38 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 39 | driver.findElementByXPath("//android.widget.TextView[@text='支持作者']").click(); 40 | driver.findElementById("android:id/button3").click(); 41 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 42 | driver.findElementByXPath("//android.widget.TextView[@text='支持作者']").click(); 43 | driver.findElementById("android:id/button1").click(); 44 | 45 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 46 | driver.findElementByXPath("//android.widget.TextView[@text='去评分']").click(); 47 | driver.sendKeyEvent(AndroidKeyCode.BACK); 48 | driver.sendKeyEvent(AndroidKeyCode.BACK); 49 | waitForActivity(driver, "MainActivity"); 50 | 51 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 52 | driver.findElementByXPath("//android.widget.TextView[@text='关于(1.8.0)']").click(); 53 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 54 | 55 | driver.findElementByXPath("//android.widget.ImageView[@content-desc='更多选项']").click(); 56 | driver.findElementByXPath("//android.widget.TextView[@text='设置']").click(); 57 | driver.findElementByXPath("//android.widget.Button[@text='知道了']").click(); 58 | driver.findElementByXPath("//android.widget.TextView[@text='开启划词翻译']").click(); 59 | driver.findElementByXPath("//android.widget.TextView[@text='开启自动发音']").click(); 60 | driver.findElementByXPath("//android.widget.TextView[@text='打开 App 自动翻译粘贴板单词']").click(); 61 | driver.findElementByXPath("//android.widget.TextView[@text='开启定时单词提醒']").click(); 62 | driver.findElementByXPath("//android.widget.TextView[@text='背单词提示间隔时间']").click(); 63 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='半小时']").click(); 64 | driver.findElementByXPath("//android.widget.TextView[@text='提示显示时间']").click(); 65 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='2秒钟']").click(); 66 | driver.findElementByXPath("//android.widget.TextView[@text='开启单词联想输入']").click(); 67 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 68 | 69 | driver.findElementById("android:id/input").sendKeys("test"); 70 | driver.findElementById("name.gudong.translate:id/tv_clear").click(); 71 | driver.findElementById("android:id/input").sendKeys("test"); 72 | driver.findElementById("android:id/input").click(); 73 | driver.findElementById("name.gudong.translate:id/sp_translate_way").click(); 74 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='金山']").click(); 75 | driver.findElementById("name.gudong.translate:id/sp_translate_way").click(); 76 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='谷歌']").click(); 77 | driver.findElementById("name.gudong.translate:id/sp_translate_way").click(); 78 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='百度']").click(); 79 | driver.findElementById("name.gudong.translate:id/sp_translate_way").click(); 80 | driver.findElementByXPath("//android.widget.CheckedTextView[@text='有道']").click(); 81 | driver.findElementById("name.gudong.translate:id/bt_translate").click(); 82 | 83 | driver.findElementById("name.gudong.translate:id/iv_favorite").click(); 84 | driver.findElementById("name.gudong.translate:id/iv_sound").click(); 85 | driver.findElementById("name.gudong.translate:id/iv_paste").click(); 86 | } 87 | 88 | private void waitForActivity(AppiumDriver driver, String activity) { 89 | activity = "." + activity; 90 | while (!driver.currentActivity().contains(activity)) { 91 | System.out.println("- Waiting for " + activity); 92 | Thread.yield(); 93 | } 94 | System.out.println(">> Begin " + activity); 95 | } 96 | 97 | /** 98 | * AppiumDriver的初始化逻辑必须写在该函数中 99 | * 100 | * @return 101 | */ 102 | public AppiumDriver initAppiumTest() { 103 | 104 | AppiumDriver driver = null; 105 | File classpathRoot = new File(System.getProperty("user.dir")); 106 | File appDir = new File(classpathRoot, "apk"); 107 | File app = new File(appDir, "GuDong.apk"); 108 | 109 | //设置自动化相关参数 110 | DesiredCapabilities capabilities = new DesiredCapabilities(); 111 | capabilities.setCapability("automationName", "UiAutomator2"); 112 | capabilities.setCapability("browserName", ""); 113 | capabilities.setCapability("platformName", "Android"); 114 | capabilities.setCapability("deviceName", "Android Emulator"); 115 | capabilities.setCapability("appPackage", "name.gudong.translate"); 116 | capabilities.setCapability("appActivity", "name.gudong.translate.ui.activitys.MainActivity"); 117 | capabilities.setCapability("noSign", "true"); 118 | 119 | //设置apk路径 120 | capabilities.setCapability("app", app.getAbsolutePath()); 121 | 122 | //设置使用unicode键盘,支持输入中文和特殊字符 123 | capabilities.setCapability("unicodeKeyboard", "true"); 124 | //设置用例执行完成后重置键盘 125 | capabilities.setCapability("resetKeyboard", "true"); 126 | //初始化 127 | try { 128 | driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 129 | } catch (MalformedURLException e) { 130 | // TODO Auto-generated catch block 131 | e.printStackTrace(); 132 | } 133 | return driver; 134 | } 135 | 136 | public void start() { 137 | test(initAppiumTest()); 138 | } 139 | 140 | public static void main(String[] args) { 141 | Main main = new Main(); 142 | main.start(); 143 | } 144 | 145 | 146 | } -------------------------------------------------------------------------------- /Appium/Meituan/src/com/mooctest/Main.java: -------------------------------------------------------------------------------- 1 | package com.mooctest; 2 | 3 | import io.appium.java_client.AndroidKeyCode; 4 | import io.appium.java_client.AppiumDriver; 5 | import org.openqa.selenium.remote.DesiredCapabilities; 6 | 7 | import java.io.File; 8 | import java.net.MalformedURLException; 9 | import java.net.URL; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | 13 | public class Main { 14 | 15 | /** 16 | * 所有和AppiumDriver相关的操作都必须写在该函数中 17 | * 18 | * @param driver 19 | */ 20 | public void test(AppiumDriver driver) { 21 | driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS); //设置尝试定位控件的最长时间为8s,也就是最多尝试8s 22 | /* 23 | * 余下的测试逻辑请按照题目要求进行编写 24 | */ 25 | waitForActivity(driver, "MainActivity"); 26 | driver.findElementById("com.sankuai.meituan:id/city_button").click(); 27 | try { 28 | Thread.sleep(3000); 29 | } catch (InterruptedException e) { 30 | e.printStackTrace(); 31 | } 32 | driver.findElementsByXPath("//android.widget.TextView[@text='南京']").get(1).click(); 33 | 34 | driver.findElementByXPath("//android.view.View[@content-desc='附近']").click(); 35 | driver.findElementByXPath("//android.view.View[@content-desc='发现']").click(); 36 | driver.findElementByXPath("//android.view.View[@content-desc='订单']").click(); 37 | driver.findElementByXPath("//android.view.View[@content-desc='我的']").click(); 38 | driver.findElementByXPath("//android.view.View[@content-desc='首页']").click(); 39 | 40 | driver.findElementByXPath("//android.view.View[@content-desc='美食']").click(); 41 | driver.findElementByXPath("//android.widget.TextView[@text='优惠团购']").click(); 42 | driver.sendKeyEvent(AndroidKeyCode.BACK); 43 | driver.findElementByXPath("//android.widget.TextView[@text='附近好券']").click(); 44 | driver.sendKeyEvent(AndroidKeyCode.BACK); 45 | driver.findElementByXPath("//android.widget.TextView[@text='预约订座']").click(); 46 | driver.sendKeyEvent(AndroidKeyCode.BACK); 47 | driver.findElementByXPath("//android.widget.TextView[@text='外卖']").click(); 48 | try { 49 | Thread.sleep(3000); 50 | } catch (InterruptedException e) { 51 | e.printStackTrace(); 52 | } 53 | driver.sendKeyEvent(AndroidKeyCode.BACK); 54 | driver.findElementByXPath("//android.widget.TextView[@text='新店特惠']").click(); 55 | driver.sendKeyEvent(AndroidKeyCode.BACK); 56 | driver.findElementByXPath("//android.widget.TextView[@text='自助餐']").click(); 57 | driver.sendKeyEvent(AndroidKeyCode.BACK); 58 | driver.findElementByXPath("//android.widget.TextView[@text='火锅']").click(); 59 | driver.sendKeyEvent(AndroidKeyCode.BACK); 60 | driver.findElementByXPath("//android.widget.TextView[@text='江浙菜']").click(); 61 | driver.sendKeyEvent(AndroidKeyCode.BACK); 62 | 63 | driver.findElementById("com.sankuai.meituan:id/food_list_map_menu_img").click(); 64 | driver.findElementById("com.sankuai.meituan:id/food_search_header_search").click(); 65 | driver.findElementByXPath("//android.widget.TextView[@text='新街口地区']").click(); 66 | driver.findElementById("com.sankuai.meituan:id/food_map_location_button").click(); 67 | driver.findElementById("com.sankuai.meituan:id/food_search_header_back").click(); 68 | 69 | driver.findElementById("com.sankuai.meituan:id/tv_search_text").click(); 70 | driver.findElementById("com.sankuai.meituan:id/search_edit").sendKeys("小龙虾"); 71 | driver.findElementById("com.sankuai.meituan:id/search").click(); 72 | driver.findElementById("com.sankuai.meituan:id/category").click(); 73 | driver.findElementByXPath("//android.widget.TextView[@text='美食']").click(); 74 | driver.findElementById("com.sankuai.meituan:id/category").click(); 75 | driver.swipe(800, 600, 800, 200, 500); 76 | driver.swipe(800, 600, 800, 200, 500); 77 | driver.swipe(800, 600, 800, 200, 500); 78 | driver.swipe(800, 600, 800, 200, 500); 79 | driver.swipe(800, 600, 800, 200, 500); 80 | driver.findElementByXPath("//android.widget.TextView[@text='海鲜']").click(); 81 | driver.findElementById("com.sankuai.meituan:id/area").click(); 82 | driver.findElementByXPath("//android.widget.TextView[@text='鼓楼区']").click(); 83 | driver.findElementByXPath("//android.widget.TextView[@text='新街口/金轮/五台山体育中心']").click(); 84 | driver.findElementById("com.sankuai.meituan:id/sort").click(); 85 | driver.findElementByXPath("//android.widget.TextView[@text='好评优先']").click(); 86 | driver.findElementById("com.sankuai.meituan:id/senior_filter").click(); 87 | driver.findElementByXPath("//android.widget.TextView[@text='5~10人餐']").click(); 88 | driver.findElementById("com.sankuai.meituan:id/bottom_confirm").click(); 89 | 90 | driver.findElementsById("com.sankuai.meituan:id/image").get(0).click(); 91 | driver.findElementById("com.sankuai.meituan:id/favor").click(); 92 | driver.findElementById("com.sankuai.meituan:id/share").click(); 93 | driver.findElementById("com.sankuai.meituan:id/share_cancel").click(); 94 | driver.findElementById("com.sankuai.meituan:id/share").click(); 95 | driver.findElementByXPath("//android.widget.TextView[@text='微信好友']"); //.click(); 96 | // driver.sendKeyEvent(AndroidKeyCode.BACK); 97 | driver.findElementByXPath("//android.widget.TextView[@text='朋友圈']"); //.click(); 98 | // driver.sendKeyEvent(AndroidKeyCode.BACK); 99 | driver.findElementByXPath("//android.widget.TextView[@text='复制']").click(); 100 | driver.findElementById("com.sankuai.meituan:id/share").click(); 101 | driver.findElementByXPath("//android.widget.TextView[@text='更多']").click(); 102 | driver.sendKeyEvent(AndroidKeyCode.BACK); 103 | 104 | driver.findElementById("com.sankuai.meituan:id/food_poi_top_image").click(); 105 | driver.findElementByXPath("//android.widget.ImageButton[@content-desc='转到上一层级']").click(); 106 | driver.findElementById("com.sankuai.meituan:id/food_poi_address_container").click(); 107 | driver.findElementById("com.sankuai.meituan:id/food_header_back").click(); 108 | driver.findElementById("com.sankuai.meituan:id/food_poi_taxi_img").click(); 109 | driver.sendKeyEvent(AndroidKeyCode.BACK); 110 | driver.findElementById("com.sankuai.meituan:id/food_poi_telephone_img").click(); 111 | driver.sendKeyEvent(AndroidKeyCode.BACK); 112 | driver.findElementByXPath("//android.widget.TextView[@text='优惠信息']").click(); 113 | driver.findElementByXPath("//android.widget.TextView[@text='用户评论']").click(); 114 | driver.findElementByXPath("//android.widget.TextView[@text='商家信息']").click(); 115 | 116 | driver.quit(); 117 | } 118 | 119 | private void waitForActivity(AppiumDriver driver, String activity) { 120 | activity = "." + activity; 121 | while (!driver.currentActivity().contains(activity)) { 122 | System.out.println("- Waiting for " + activity); 123 | Thread.yield(); 124 | } 125 | System.out.println(">> Begin " + activity); 126 | } 127 | 128 | /** 129 | * AppiumDriver的初始化逻辑必须写在该函数中 130 | * 131 | * @return 132 | */ 133 | public AppiumDriver initAppiumTest() { 134 | 135 | AppiumDriver driver = null; 136 | File classpathRoot = new File(System.getProperty("user.dir")); 137 | File appDir = new File(classpathRoot, "apk"); 138 | File app = new File(appDir, "Meituan.apk"); 139 | 140 | //设置自动化相关参数 141 | DesiredCapabilities capabilities = new DesiredCapabilities(); 142 | capabilities.setCapability("automationName", "UiAutomator2"); 143 | capabilities.setCapability("browserName", ""); 144 | capabilities.setCapability("platformName", "Android"); 145 | capabilities.setCapability("deviceName", "Android Emulator"); 146 | //设置apk路径 147 | capabilities.setCapability("app", app.getAbsolutePath()); 148 | capabilities.setCapability("appPackage", "com.sankuai.meituan"); 149 | capabilities.setCapability("appActivity", "com.meituan.android.pt.homepage.activity.Welcome"); 150 | 151 | //设置使用unicode键盘,支持输入中文和特殊字符 152 | capabilities.setCapability("unicodeKeyboard", "true"); 153 | //设置用例执行完成后重置键盘 154 | capabilities.setCapability("resetKeyboard", "true"); 155 | capabilities.setCapability("noSign", "true"); 156 | 157 | //初始化 158 | try { 159 | driver = new AppiumDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities); 160 | } catch (MalformedURLException e) { 161 | // TODO Auto-generated catch block 162 | e.printStackTrace(); 163 | } 164 | return driver; 165 | } 166 | 167 | public void start() { 168 | test(initAppiumTest()); 169 | } 170 | 171 | public static void main(String[] args) { 172 | Main main = new Main(); 173 | main.start(); 174 | } 175 | 176 | 177 | } -------------------------------------------------------------------------------- /JUnit/ALU/src/test/java/net/mooctest/ALUTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.OutputStream; 7 | import java.io.PrintStream; 8 | 9 | import static org.junit.Assert.assertEquals; 10 | import static org.junit.Assert.assertTrue; 11 | 12 | public class ALUTest { 13 | 14 | @Test(timeout = 4000) 15 | public void test() { 16 | ALU alu = new ALU(); 17 | 18 | assertEquals("0000000011101001", alu.integerRepresentation("233", 16)); 19 | assertEquals("1111111100010111", alu.integerRepresentation("-233", 16)); 20 | 21 | assertEquals("01000000010010010000111111011010", alu.ieee754("3.1415926", 32)); 22 | assertEquals("1100000000001000000000000000000000000000000000000000000000000000", alu.ieee754("-3.00", 64)); 23 | assertEquals("0000000000000000000000000000000000000000000000000000000000000000", alu.ieee754("0.0", 64)); 24 | assertEquals("0011111111001101110100101111000111000000000000000000000000000000", alu.ieee754("0.233", 64)); 25 | assertEquals("0100000001101101001", alu.ieee754("233", 64)); 26 | assertEquals("", alu.ieee754("3.1415926", 0)); 27 | // 28 | assertEquals("0000001000", alu.floatRepresentation("0.01", 4, 5)); 29 | 30 | OutputStream os = new ByteArrayOutputStream(); 31 | PrintStream ps = new PrintStream(os); 32 | System.setOut(ps); 33 | assertEquals("00010100", alu.floatRepresentation("0.01", 2, 5)); 34 | ps.flush(); 35 | assertTrue(os.toString().trim().contains("-6")); 36 | assertTrue(os.toString().trim().contains("0000001010")); 37 | 38 | assertEquals("NaN", alu.floatRepresentation(String.valueOf(Integer.MAX_VALUE), 2, 5)); 39 | assertEquals("+Inf", alu.floatRepresentation("2", -1, 1)); 40 | 41 | assertEquals("233", alu.integerTrueValue("0000000011101001")); 42 | 43 | assertEquals("11.375", alu.floatTrueValue("01000001001101100000", 8, 11)); 44 | assertEquals("-11.375", alu.floatTrueValue("11000001001101100000", 8, 11)); 45 | assertEquals("+Inf", alu.floatTrueValue("01111111100000000000", 8, 11)); 46 | assertEquals("-Inf", alu.floatTrueValue("11111111100000000000", 8, 11)); 47 | assertEquals("NaN", alu.floatTrueValue("11111111100000000001", 8, 11)); 48 | assertEquals("0", alu.floatTrueValue("10000000000000000000", 8, 11)); 49 | assertEquals("-4.9591167925315254E-39", alu.floatTrueValue("10000000001101100000", 8, 11)); 50 | 51 | assertEquals("10000", alu.oneAdder("1111")); 52 | 53 | assertEquals("000000111", alu.adder("0100", "0011", '0', 8)); 54 | assertEquals("1000111", alu.adder("1100", "1011", '0', 6)); 55 | assertEquals("0111111", alu.adder("1100", "0011", '0', 6)); 56 | 57 | assertEquals("1000", alu.leftShift("0010", 2)); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /JUnit/Anagram/src/main/java/net/mooctest/Anagram.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import java.io.IOException; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | /** 9 | * This class will implement the logic to solve multi-word anagrams 10 | * 11 | */ 12 | public class Anagram { 13 | 14 | private int minWordSize = 3; 15 | private Dictionary sortedDictionary; 16 | private String dictionaryFilePath; 17 | 18 | public Anagram(String dictionaryFilePath) { 19 | assert !dictionaryFilePath.isEmpty(); 20 | sortedDictionary = new Dictionary(); 21 | this.dictionaryFilePath = dictionaryFilePath; 22 | } 23 | 24 | public Anagram(int minWordSize, String dictionaryFilePath) { 25 | this(dictionaryFilePath); 26 | this.minWordSize = minWordSize; 27 | } 28 | 29 | /* 30 | * returns set of strings with all anagrams also prints the results on std out 31 | */ 32 | public Set> findAllAnagrams(String wordString) throws IOException { 33 | 34 | // remove all white space chars from string 35 | wordString = wordString.replaceAll("\\s", ""); 36 | Set> anagramsSet = new HashSet>(); 37 | // load dictionary for subset words 38 | sortedDictionary.loadDictionaryWithSubsets(dictionaryFilePath, wordString, minWordSize); 39 | List keyList = sortedDictionary.getDictionaryKeyList(); 40 | 41 | int count = 0; 42 | // check for all the words in key list for anagrams 43 | for (int index = 0; index < keyList.size(); index++) { 44 | char[] charInventory = wordString.toCharArray(); 45 | Set> dictWordAnagramsSet = findAnagrams(index, charInventory, keyList); 46 | Set> tempAnagramSet = new HashSet>(); 47 | if (dictWordAnagramsSet != null && !dictWordAnagramsSet.isEmpty()) { 48 | Set> mergeResult = null; 49 | for (Set anagramSet : dictWordAnagramsSet) { 50 | mergeResult = mergeAnagramKeyWords(anagramSet); 51 | tempAnagramSet.addAll(mergeResult); 52 | } 53 | System.out.println(""); 54 | System.out.println("\t(" + sortedDictionary.findSingleWordAnagrams(keyList.get(index)).toString() 55 | .replace(",", "") + ")"); 56 | for (Set anagramSet : tempAnagramSet) { 57 | System.out.println("" + ++count + ".\t" + anagramSet.toString().replace(",", "")); 58 | } 59 | anagramsSet.addAll(tempAnagramSet); 60 | } 61 | } 62 | 63 | return anagramsSet; 64 | } 65 | 66 | 67 | // recursive function to find all the anagrams for charInventory characters 68 | // starting with the word at dictionaryIndex in dictionary keyList 69 | private Set> findAnagrams(int dictionaryIndex, char[] charInventory, List keyList) { 70 | // terminating condition if no words are found 71 | if (dictionaryIndex >= keyList.size() || charInventory.length < minWordSize) { 72 | return null; 73 | } 74 | 75 | String searchWord = keyList.get(dictionaryIndex); 76 | char[] searchWordChars = searchWord.toCharArray(); 77 | // this is where you find the anagrams for whole word 78 | if (Helper.isEquivalent(searchWordChars, charInventory)) { 79 | Set> anagramsSet = new HashSet>(); 80 | Set anagramSet = new HashSet(); 81 | anagramSet.add(searchWord); 82 | anagramsSet.add(anagramSet); 83 | 84 | return anagramsSet; 85 | } 86 | 87 | // this is where you find the anagrams with multiple words 88 | if (Helper.isSubset(searchWordChars, charInventory)) { 89 | // update charInventory by removing the characters of the search 90 | // word as it is subset of characters for the anagram search word 91 | char[] newCharInventory = Helper.setDifference(charInventory, searchWordChars); 92 | if (newCharInventory.length >= minWordSize) { 93 | Set> anagramsSet = new HashSet>(); 94 | for (int index = dictionaryIndex + 1; index < keyList.size(); index++) { 95 | Set> searchWordAnagramsKeysSet = findAnagrams(index, newCharInventory, keyList); 96 | if (searchWordAnagramsKeysSet != null) { 97 | Set> mergedSets = mergeWordToSets(searchWord, searchWordAnagramsKeysSet); 98 | anagramsSet.addAll(mergedSets); 99 | } 100 | } 101 | return anagramsSet.isEmpty() ? null : anagramsSet; 102 | } 103 | } 104 | 105 | // no anagrams found for current word 106 | return null; 107 | } 108 | 109 | // this function will merge the real dictionary words found under the sorted key word 110 | // for e.g. if the set of words to be merged are [elt, aet] 111 | // and the real dictionary words for 'elt' are [let, tel] 112 | // and the real dictionary words for 'aet' are [eat, tea] 113 | // then the merged set would be [[let, eat], [let, tea], [tel, eat], [tel, tea]] 114 | private Set> mergeAnagramKeyWords( 115 | Set anagramKeySet) { 116 | if (anagramKeySet == null) { 117 | throw new IllegalStateException("anagram keys set cannot be null"); 118 | } 119 | Set> anagramsSet = new HashSet>(); 120 | for (String word : anagramKeySet) { 121 | Set anagramWordSet = sortedDictionary.findSingleWordAnagrams(word); 122 | anagramsSet.add(anagramWordSet); 123 | } 124 | @SuppressWarnings("unchecked") // cannot use generics with Set array - Java bug??? 125 | Set[] anagramsSetArray = anagramsSet.toArray(new Set[0]); 126 | 127 | return Helper.setMultiplication(anagramsSetArray); 128 | } 129 | 130 | // add word to all the sets 131 | private Set> mergeWordToSets(String word, Set> sets) { 132 | assert !word.isEmpty(); 133 | if (sets == null) { 134 | return null; 135 | } 136 | Set> mergedSets = new HashSet>(); 137 | for (Set set : sets) { 138 | if (set == null) { 139 | throw new IllegalStateException("anagram keys set cannot be null"); 140 | } 141 | set.add(word); 142 | mergedSets.add(set); 143 | } 144 | 145 | return mergedSets; 146 | } 147 | 148 | /* 149 | * prints usage instructions 150 | */ 151 | private static void usage() { 152 | 153 | System.out.println("Usage:"); 154 | System.out.println("\tjava -cp AnagramSolver.jar com.parthparekh.algorithms.AnagramSolver " + 155 | " "); 156 | System.out.println(""); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /JUnit/Anagram/src/main/java/net/mooctest/Dictionary.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Set; 12 | import java.util.TreeMap; 13 | import java.util.TreeSet; 14 | 15 | /* 16 | * data structure to store the dictionary of words with sorted keys 17 | * 18 | */ 19 | public class Dictionary { 20 | 21 | // below map will store string with sorted characters as key and all the anagrams of that string as value 22 | private final Map> sortedStringMap = new TreeMap>(); 23 | private boolean isDictionaryLoaded = false; 24 | 25 | /* 26 | * loads the words from wordlist file into map; it assumes the wordlist file contains words delimited by newline 27 | * i.e. \n 28 | * 29 | * @param filePath absolute file path of the wordlist (assuming it's in the classpath) 30 | */ 31 | public void loadDictionary(String filePath) throws IOException { 32 | 33 | loadDictionaryWithSubsets(filePath, null, 0); 34 | } 35 | 36 | /* 37 | * loads only the words that are subsets of wordString from wordlist file into map; 38 | * it assumes the wordlist file contains words delimited by newline i.e. \n 39 | * 40 | * @param filePath absolute file path of the wordlist (assuming it's in the classpath) 41 | * 42 | * @param wordString string to check for subsets 43 | * 44 | * @param minWordSize minimum word size to load from dictionary 45 | */ 46 | public void loadDictionaryWithSubsets(String filePath, String wordString, 47 | int minWordSize) throws IOException { 48 | 49 | if (filePath == null || filePath.isEmpty()) { 50 | throw new IllegalArgumentException("file path invalid"); 51 | } 52 | 53 | try { 54 | File file = new File(filePath); 55 | BufferedReader reader = new BufferedReader(new InputStreamReader( 56 | new FileInputStream(file))); 57 | String word; 58 | while ((word = reader.readLine()) != null) { 59 | assert word != null; 60 | word = word.trim().toLowerCase(); 61 | String sortedWord = Helper.sortWord(word); 62 | if (sortedWord == null 63 | || sortedWord.isEmpty() 64 | || (wordString != null && !wordString.isEmpty() && (sortedWord 65 | .length() < minWordSize || !Helper 66 | .isSubset(sortedWord.toCharArray(), wordString 67 | .replaceAll("\\s", "").toLowerCase() 68 | .toCharArray())))) { 69 | // don't add the word to dictionary if word is empty or if 70 | // word from word-list is not a subset of wordString or word 71 | // is less than minWordSize 72 | continue; 73 | } 74 | Set wordSet = sortedStringMap.get(sortedWord); 75 | if (wordSet != null) { 76 | // add word to the existing wordset 77 | wordSet.add(word); 78 | } else { 79 | wordSet = new TreeSet(); 80 | wordSet.add(word); 81 | sortedStringMap.put(sortedWord, wordSet); 82 | } 83 | } 84 | 85 | reader.close(); 86 | isDictionaryLoaded = true; 87 | } catch (IOException ioException) { 88 | throw ioException; 89 | } 90 | } 91 | 92 | /* 93 | * adds word to dictionary 94 | * 95 | * @param wordString adds wordString to current dictionary 96 | * 97 | * @return true if the word is successfully added, false otherwise 98 | */ 99 | public boolean addWord(String wordString) { 100 | 101 | if (wordString.isEmpty()) { 102 | return false; 103 | } 104 | 105 | String sortedWord = Helper.sortWord(wordString); 106 | Set wordSet = sortedStringMap.get(sortedWord); 107 | if (wordSet != null) { 108 | // add word to the existing words set 109 | wordSet.add(wordString); 110 | } else { 111 | // add create new words set 112 | wordSet = new TreeSet(); 113 | wordSet.add(wordString); 114 | sortedStringMap.put(sortedWord, wordSet); 115 | } 116 | 117 | return true; 118 | } 119 | 120 | /* 121 | * finds all the anagrams of the word in the dictionary 122 | * 123 | * @param wordString word for which anagrams are to be found 124 | * 125 | * @return set of single word anagrams for given string 126 | */ 127 | public Set findSingleWordAnagrams(String wordString) { 128 | 129 | if (!isDictionaryLoaded) { 130 | throw new IllegalStateException("dictionary not loaded"); 131 | } else { 132 | 133 | if (wordString == null || wordString.isEmpty()) { 134 | throw new IllegalStateException("word string invalid"); 135 | } 136 | return sortedStringMap 137 | .get(Helper.sortWord(wordString)); 138 | } 139 | } 140 | 141 | /* 142 | * get list for all the keys in dictionary 143 | * 144 | * @return returns the list of all the keys 145 | */ 146 | public List getDictionaryKeyList() { 147 | assert sortedStringMap != null; 148 | return new ArrayList(sortedStringMap.keySet()); 149 | } 150 | 151 | public boolean isDictionaryLoaded() { 152 | return isDictionaryLoaded; 153 | } 154 | 155 | @Override 156 | public String toString() { 157 | return "isDictionaryLoaded?: " + isDictionaryLoaded + "\nDictionary: " + sortedStringMap; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /JUnit/Anagram/src/main/java/net/mooctest/Helper.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | /** 10 | * this is a helper class holding all the static methods useful for solving anagrams 11 | * 12 | */ 13 | public class Helper { 14 | 15 | /* 16 | * sort the characters in word string 17 | * 18 | * @param wordString - string to sort 19 | * 20 | * @return string with sorted characters 21 | */ 22 | public static String sortWord(String wordString) { 23 | if (wordString.isEmpty()) { 24 | return null; 25 | } 26 | byte[] charBytes = wordString.getBytes(); 27 | Arrays.sort(charBytes); 28 | 29 | return new String(charBytes); 30 | } 31 | 32 | /* 33 | * checks if the first character array is subset of second character array 34 | * 35 | * @param charArr1 - character array charArr1 to check for subset 36 | * 37 | * @param charArr2 - checking for subset against character array charArr2 38 | * 39 | * @return true is charArray1 is subset of charArray2, false otherwise 40 | */ 41 | public static boolean isSubset(char[] charArr1, char[] charArr2) { 42 | if (charArr1.length > charArr2.length) { 43 | return false; 44 | } 45 | List charList1 = toList(charArr1); 46 | List charList2 = toList(charArr2); 47 | // cannot do containsAll as there can be duplicate characters 48 | for (Character charValue : charList1) { 49 | if (charList2.contains(charValue)) { 50 | charList2.remove(charValue); 51 | } else { 52 | return false; 53 | } 54 | } 55 | return true; 56 | } 57 | 58 | /* 59 | * converts character array to character list 60 | */ 61 | private static List toList(char[] charArr) { 62 | assert charArr != null; 63 | List charList = new ArrayList(); 64 | for (char ch : charArr) { 65 | charList.add(ch); 66 | } 67 | return charList; 68 | } 69 | 70 | /* 71 | * converts character list to character array 72 | */ 73 | private static char[] toCharArray(List charList) { 74 | if (charList == null || charList.isEmpty()) { 75 | return new char[0]; 76 | } 77 | 78 | char[] charArr = new char[charList.size()]; 79 | for (int index = 0; index < charList.size(); index++) { 80 | charArr[index] = charList.get(index); 81 | } 82 | return charArr; 83 | } 84 | 85 | /* 86 | * checks if two character arrays are equivalent; 87 | * char arrays are equivalent if: 88 | * 1. the number of elements in them are equal, and 89 | * 2. all the elements are same (not necessarily in same order) 90 | * complexity should be O(n) 91 | * 92 | * @param charArr1 - first character array for equivalence check 93 | * 94 | * @param charArr2 - second character array for equivalence check 95 | * 96 | * @return true is charArr1 is equivalent to charArr2, false otherwise 97 | */ 98 | public static boolean isEquivalent(char[] charArr1, char[] charArr2) { 99 | if (charArr1.length != charArr2.length) { 100 | return false; 101 | } 102 | int sum1 = 0; 103 | int sum2 = 0; 104 | for (int index = 0; index < charArr1.length; index++) { 105 | sum1 += charArr1[index]; 106 | sum2 += charArr2[index]; 107 | } 108 | // in most cases it would return from here 109 | if (sum1 != sum2) { 110 | return false; 111 | } 112 | List charList1 = toList(charArr1); 113 | List charList2 = toList(charArr2); 114 | for (Character charValue : charList1) { 115 | charList2.remove(charValue); 116 | } 117 | return charList2.isEmpty(); 118 | } 119 | 120 | /* 121 | * calculates set difference for 2 character arrays i.e. charArr1 - charArr2 removes all charArr2 elements from charArr1 122 | * complexity should be O(n) 123 | * 124 | * @param charArr1 - first character array for set difference 125 | * 126 | * @param charArr2 - second character array for set difference 127 | * 128 | * @return resultant character array of set difference between charArr1 and charArr2 129 | */ 130 | public static char[] setDifference(char[] charArr1, char[] charArr2) { 131 | List list1 = toList(charArr1); 132 | List list2 = toList(charArr2); 133 | for (Character charObj : list2) { 134 | list1.remove(charObj); 135 | } 136 | return toCharArray(list1); 137 | } 138 | 139 | /* 140 | * function to perform set multiplication of all the sets of strings passed 141 | * 142 | * @param setsArray - muliple sets to multiply (can be a set of strings array) 143 | * 144 | * @return returns set consisting of set of strings after cartesian product is applied 145 | */ 146 | public static Set> setMultiplication(Set... setsArray) { 147 | if (setsArray == null || setsArray.length == 0) { 148 | return null; 149 | } 150 | return setMultiplication(0, setsArray); 151 | } 152 | 153 | // recursive function to calculate the cartesian product of all the sets of strings passed 154 | private static Set> setMultiplication(int index, Set... setsArray) { 155 | Set> setsMultiplied = new HashSet>(); 156 | if (index == setsArray.length) { 157 | setsMultiplied.add(new HashSet()); 158 | } else { 159 | for (String obj : setsArray[index]) { 160 | for (Set set : setMultiplication(index + 1, setsArray)) { 161 | set.add(obj); 162 | setsMultiplied.add(set); 163 | } 164 | } 165 | } 166 | 167 | return setsMultiplied; 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /JUnit/Anagram/src/main/resources/net/mooctest/demo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepAQ/SoftwareTesting/9ee0a11c136fc8737e023da19a203381ef5728a3/JUnit/Anagram/src/main/resources/net/mooctest/demo.txt -------------------------------------------------------------------------------- /JUnit/Anagram/src/test/java/net/mooctest/AnagramTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.ByteArrayOutputStream; 7 | import java.io.IOException; 8 | import java.io.PrintStream; 9 | import java.lang.reflect.Method; 10 | import java.util.Set; 11 | 12 | public class AnagramTest { 13 | // @Test 14 | // public void testConstruct() { 15 | // try { 16 | // new Anagram(""); 17 | // } catch (AssertionError e) { 18 | // return; 19 | // } 20 | // Assert.fail(); 21 | // } 22 | 23 | @Test 24 | public void testUsage() throws Exception { 25 | PrintStream sysOut = System.out; 26 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 27 | System.setOut(new PrintStream(os)); 28 | 29 | Method usage = Anagram.class.getDeclaredMethod("usage"); 30 | usage.setAccessible(true); 31 | usage.invoke(null); 32 | 33 | System.setOut(sysOut); 34 | os.close(); 35 | String out = os.toString(); 36 | 37 | Assert.assertTrue(out.contains("Usage:")); 38 | Assert.assertTrue(out.contains("\tjava -cp AnagramSolver.jar com.parthparekh.algorithms.AnagramSolver ")); 39 | Assert.assertTrue(out.contains("\n\n") || out.contains("\n\r")); 40 | } 41 | 42 | @Test 43 | public void testFindAnagram() throws IOException { 44 | PrintStream sysOut = System.out; 45 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 46 | System.setOut(new PrintStream(os)); 47 | 48 | Anagram anagram = new Anagram(3, "wordlist.txt"); 49 | Set> result = anagram.findAllAnagrams("listen"); 50 | 51 | System.setOut(sysOut); 52 | os.close(); 53 | String out = os.toString(); 54 | 55 | Assert.assertEquals(10, result.size()); 56 | Assert.assertTrue(out.contains("([enlist inlets listen silent tinsel])")); 57 | Assert.assertTrue(out.contains("[tinsel]")); 58 | Assert.assertTrue(out.contains("([let])")); 59 | Assert.assertTrue(out.contains("[let ins]")); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /JUnit/Anagram/src/test/java/net/mooctest/DictionaryTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.IOException; 7 | 8 | public class DictionaryTest { 9 | @Test 10 | public void testLoad() throws IOException { 11 | Dictionary dict = new Dictionary(); 12 | Assert.assertFalse(dict.isDictionaryLoaded()); 13 | dict.loadDictionary("wordlist.txt"); 14 | Assert.assertTrue(dict.isDictionaryLoaded()); 15 | } 16 | 17 | @Test 18 | public void testLoadInvalid() throws IOException { 19 | Dictionary dict = new Dictionary(); 20 | Assert.assertFalse(dict.isDictionaryLoaded()); 21 | 22 | try { 23 | dict.loadDictionary(null); 24 | Assert.fail(); 25 | } catch (IllegalArgumentException e) { 26 | Assert.assertEquals("file path invalid", e.getMessage()); 27 | } 28 | Assert.assertFalse(dict.isDictionaryLoaded()); 29 | 30 | try { 31 | dict.loadDictionary(""); 32 | Assert.fail(); 33 | } catch (IllegalArgumentException e) { 34 | Assert.assertEquals("file path invalid", e.getMessage()); 35 | } 36 | Assert.assertFalse(dict.isDictionaryLoaded()); 37 | 38 | try { 39 | dict.loadDictionary("???"); 40 | Assert.fail(); 41 | } catch (IOException e) { 42 | } 43 | Assert.assertFalse(dict.isDictionaryLoaded()); 44 | } 45 | 46 | @Test 47 | public void testAddWords() throws IOException { 48 | Dictionary dict = new Dictionary(); 49 | Assert.assertEquals("isDictionaryLoaded?: false\nDictionary: {}", dict.toString()); 50 | try { 51 | dict.addWord(null); 52 | Assert.fail(); 53 | } catch (NullPointerException e) { 54 | } 55 | Assert.assertFalse(dict.addWord("")); 56 | Assert.assertEquals(0, dict.getDictionaryKeyList().size()); 57 | 58 | Assert.assertTrue(dict.addWord("listen")); 59 | Assert.assertEquals(1, dict.getDictionaryKeyList().size()); 60 | Assert.assertTrue(dict.addWord("tinsel")); 61 | Assert.assertEquals(1, dict.getDictionaryKeyList().size()); 62 | Assert.assertEquals("eilnst", dict.getDictionaryKeyList().get(0)); 63 | 64 | Assert.assertTrue(dict.addWord("apple")); 65 | Assert.assertEquals(2, dict.getDictionaryKeyList().size()); 66 | Assert.assertEquals("aelpp", dict.getDictionaryKeyList().get(0)); 67 | } 68 | 69 | @Test 70 | public void testIllegalStates() throws IOException { 71 | Dictionary dict = new Dictionary(); 72 | try { 73 | dict.findSingleWordAnagrams("test"); 74 | Assert.fail(); 75 | } catch (IllegalStateException e) { 76 | Assert.assertEquals("dictionary not loaded", e.getMessage()); 77 | } 78 | 79 | dict.loadDictionary("wordlist.txt"); 80 | try { 81 | dict.findSingleWordAnagrams(""); 82 | Assert.fail(); 83 | } catch (IllegalStateException e) { 84 | Assert.assertEquals("word string invalid", e.getMessage()); 85 | } 86 | try { 87 | dict.findSingleWordAnagrams(null); 88 | Assert.fail(); 89 | } catch (IllegalStateException e) { 90 | Assert.assertEquals("word string invalid", e.getMessage()); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /JUnit/Anagram/src/test/java/net/mooctest/HelperTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.IOException; 7 | import java.lang.reflect.Method; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | public class HelperTest { 13 | @Test 14 | public void testAssertNonNull() throws IOException { 15 | try { 16 | Helper.setDifference(null, null); 17 | } catch (Throwable t) { 18 | return; 19 | } 20 | Assert.fail(); 21 | } 22 | 23 | @Test 24 | public void testToCharArray() throws Exception { 25 | Method toCharArray = Helper.class.getDeclaredMethod("toCharArray", List.class); 26 | toCharArray.setAccessible(true); 27 | Assert.assertEquals(0, ((char[]) toCharArray.invoke(null, new Object[]{null})).length); 28 | Assert.assertEquals(0, ((char[]) toCharArray.invoke(null, Collections.emptyList())).length); 29 | } 30 | 31 | @Test 32 | public void testSetMultiplication() throws Exception { 33 | Method setMultiplication = Helper.class.getDeclaredMethod("setMultiplication", Set[].class); 34 | Assert.assertNull(setMultiplication.invoke(null, new Object[]{null})); 35 | Assert.assertNull(setMultiplication.invoke(null, new Object[]{new Set[0]})); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /JUnit/ArgsParser/src/ArgsParser.java: -------------------------------------------------------------------------------- 1 | /* dcParseArgs - Java library to simplify args[] handling 2 | * 3 | * Copyright (C) 2008 Roland Koller 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3.0 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | public class ArgsParser { 25 | 26 | public static final String SHORT_ARGUMENT_INDICATOR = "-"; 27 | 28 | public static final String LONG_ARGUMENT_INDICATOR = "--"; 29 | 30 | private String[] args; /* Eine Kopie der übergebenen Parameter */ 31 | 32 | private String[] innerArgs; /* 33 | * Hier werden bereits geparste Felder mit null überschrieben 34 | */ 35 | 36 | public ArgsParser() { 37 | super(); 38 | } 39 | 40 | public ArgsParser(String[] args) { 41 | super(); 42 | this.setArgs(args); 43 | } 44 | 45 | public int getArgsCount() { 46 | return args.length; 47 | } 48 | 49 | public String[] getArgs() { 50 | return args; 51 | } 52 | 53 | public void setArgs(String[] args) { 54 | if (args == null) 55 | throw new NullPointerException("args[] cannot be null."); 56 | 57 | this.args = new String[args.length]; 58 | this.innerArgs = new String[args.length]; 59 | 60 | for (int i = 0; i < args.length; ++i) { 61 | this.args[i] = args[i]; 62 | this.innerArgs[i] = args[i]; 63 | } 64 | } 65 | 66 | public int getArgsLeftCount() { 67 | int result = 0; 68 | for (int i = 0; i < innerArgs.length; ++i) 69 | if (innerArgs[i] != null) 70 | result++; 71 | return result; 72 | } 73 | 74 | public SwitchArgument parseSwitchArgument(String key) { 75 | boolean isLongKey = (key.length() > 1); 76 | 77 | if (isLongKey) { 78 | String searchFor = LONG_ARGUMENT_INDICATOR + key; 79 | for (int i = 0; i < args.length; ++i) { 80 | if (innerArgs[i] != null) { 81 | if (innerArgs[i].equals(searchFor)) { 82 | innerArgs[i] = null; 83 | return new SwitchArgument(i, key, true); 84 | } 85 | } 86 | } 87 | } else { 88 | int index; 89 | for (int i = 0; i < args.length; ++i) { 90 | if (innerArgs[i] != null) { 91 | if (innerArgs[i].length() > 1 && (!innerArgs[i].startsWith(LONG_ARGUMENT_INDICATOR))) { 92 | index = innerArgs[i].lastIndexOf(key); 93 | if (index > 0) { 94 | String before = innerArgs[i].substring(0, index); 95 | String after = innerArgs[i].substring(index + 1, innerArgs[i].length()); 96 | innerArgs[i] = before + after; 97 | if (innerArgs[i].replace(SHORT_ARGUMENT_INDICATOR, " ").trim().length() == 0) 98 | innerArgs[i] = null; 99 | return new SwitchArgument(i, key, true); 100 | } 101 | } 102 | } 103 | } 104 | } 105 | return new SwitchArgument(-1, key, false); 106 | } 107 | 108 | public ParameterArgument parseParameterArgument(String key) { 109 | boolean isLongKey = (key.length() > 1); 110 | 111 | if (isLongKey) { 112 | String searchFor = LONG_ARGUMENT_INDICATOR + key; 113 | for (int i = 0; i < innerArgs.length; ++i) { 114 | if (innerArgs[i] != null) { 115 | if (innerArgs[i].equals(searchFor)) { 116 | if ((innerArgs.length > (i + 1)) && (innerArgs[i] != null) && (innerArgs[i + 1] != null)) { 117 | String value = innerArgs[i + 1]; 118 | innerArgs[i] = null; 119 | innerArgs[i + 1] = null; 120 | return new ParameterArgument(i, key, value); 121 | } else { 122 | /* 123 | * Ende eines der Argumentenkette trotz erwartetem Parameter oder Parameterposition wurde schon vorher als 124 | * Argument ausgewertet. 125 | */ 126 | return null; 127 | } 128 | } 129 | } 130 | } 131 | } else { 132 | 133 | int index; 134 | for (int i = 0; i < args.length; ++i) { 135 | if (innerArgs[i] != null) { 136 | if (innerArgs[i].length() > 1 && (innerArgs[i].startsWith(SHORT_ARGUMENT_INDICATOR)) 137 | && (!innerArgs[i].startsWith(LONG_ARGUMENT_INDICATOR))) { 138 | index = innerArgs[i].indexOf(key); 139 | if (index > 0) { 140 | if ((index + 1) == innerArgs[i].length()) { 141 | /* 142 | * Das letzte Element in einer Kurzargumentliste, ein Parameter muss also wenn überhaupt im nächsten 143 | * Argument liegen 144 | */ 145 | if ((innerArgs.length > (i + 1)) && (innerArgs[i] != null) && (innerArgs[i + 1]) != null) { 146 | String before = innerArgs[i].substring(0, index); 147 | String after = innerArgs[i].substring(index + 1, innerArgs[i].length()); 148 | innerArgs[i] = before + after; 149 | if (innerArgs[i].replace(SHORT_ARGUMENT_INDICATOR, " ").trim().length() == 0) 150 | innerArgs[i] = null; 151 | String value = innerArgs[i + 1]; 152 | innerArgs[i + 1] = null; 153 | return new ParameterArgument(i, key, value); 154 | } else { 155 | /* 156 | * Ende eines der Argumentenkette trotz erwartetem Parameter oder Parameterposition wurde schon vorher 157 | * als Argument ausgewertet. 158 | */ 159 | return null; 160 | } 161 | } else { 162 | /* 163 | * Nicht das letzte Element einer Kurzargumentliste, der Parameter ist damit alles nach dem Index 164 | */ 165 | String before = innerArgs[i].substring(0, index); 166 | String value = innerArgs[i].substring(index + 1, innerArgs[i].length()); 167 | innerArgs[i] = before; 168 | if (innerArgs[i].replace(SHORT_ARGUMENT_INDICATOR, " ").trim().length() == 0) 169 | innerArgs[i] = null; 170 | return new ParameterArgument(i, key, value); 171 | } 172 | } 173 | } 174 | } 175 | } 176 | 177 | } 178 | 179 | /* nicht gefunden ... */ 180 | return null; 181 | } 182 | 183 | public List parseStringArgument() { 184 | List result = new ArrayList(); 185 | for (int i = 0; i < args.length; ++i) { 186 | if (innerArgs[i] != null) { 187 | result.add(new StringArgument(i, innerArgs[i])); 188 | innerArgs[i] = null; 189 | } 190 | } 191 | return result; 192 | } 193 | 194 | } 195 | -------------------------------------------------------------------------------- /JUnit/ArgsParser/src/Argument.java: -------------------------------------------------------------------------------- 1 | /* dcParseArgs - Java library to simplify args[] handling 2 | * 3 | * Copyright (C) 2008 Roland Koller 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3.0 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | 21 | public class Argument implements Comparable { 22 | 23 | int position; 24 | 25 | public Argument(int position) { 26 | this.position = position; 27 | } 28 | 29 | public int getPosition() { 30 | return position; 31 | } 32 | 33 | public int compareTo(Argument arg0) { 34 | return position - arg0.getPosition(); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /JUnit/ArgsParser/src/KeyArgument.java: -------------------------------------------------------------------------------- 1 | /* dcParseArgs - Java library to simplify args[] handling 2 | * 3 | * Copyright (C) 2008 Roland Koller 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3.0 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | 21 | public abstract class KeyArgument extends Argument { 22 | 23 | String key; 24 | 25 | public KeyArgument(int position, String key) { 26 | super(position); 27 | if(key == null) throw new NullPointerException(); 28 | if(key.length() == 0) throw new IllegalArgumentException("Key cannot be an empty string."); 29 | this.key = key; 30 | } 31 | 32 | public boolean isLongKey() { 33 | return (key.length() > 1); 34 | } 35 | 36 | public String getKey() { 37 | return key; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /JUnit/ArgsParser/src/ParameterArgument.java: -------------------------------------------------------------------------------- 1 | /* dcParseArgs - Java library to simplify args[] handling 2 | * 3 | * Copyright (C) 2008 Roland Koller 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3.0 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | 21 | public class ParameterArgument extends KeyArgument { 22 | 23 | String value; 24 | 25 | public ParameterArgument(int position, String key, String value) { 26 | super(position, key); 27 | if(value == null) throw new NullPointerException(); 28 | if(value.length() == 0) throw new IllegalArgumentException("Value cannot be an empty string."); 29 | this.value = value; 30 | } 31 | 32 | 33 | public String getValue() { 34 | return value; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /JUnit/ArgsParser/src/StringArgument.java: -------------------------------------------------------------------------------- 1 | /* dcParseArgs - Java library to simplify args[] handling 2 | * 3 | * Copyright (C) 2008 Roland Koller 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3.0 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | public class StringArgument extends Argument { 21 | 22 | String value; 23 | 24 | public StringArgument(int position, String value) { 25 | super(position); 26 | if(value == null) throw new NullPointerException(); 27 | //if(value.length() == 0) throw new IllegalArgumentException("Value cannot be an empty string."); 28 | this.value = value; 29 | } 30 | 31 | public String getValue() { 32 | return value; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /JUnit/ArgsParser/src/SwitchArgument.java: -------------------------------------------------------------------------------- 1 | /* dcParseArgs - Java library to simplify args[] handling 2 | * 3 | * Copyright (C) 2008 Roland Koller 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 3.0 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | public class SwitchArgument extends KeyArgument { 21 | 22 | private boolean isSet; 23 | 24 | public SwitchArgument(int position, String key, boolean isSet) { 25 | super(position, key); 26 | this.isSet = isSet; 27 | } 28 | 29 | public boolean isSet() { 30 | return isSet; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /JUnit/ArgsParser/test/ArgsParserTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.After; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | public class ArgsParserTest { 10 | 11 | @Before 12 | public void setUp() throws Exception { 13 | } 14 | 15 | @After 16 | public void tearDown() throws Exception { 17 | } 18 | 19 | @Test 20 | public void testConstruct() { 21 | new ArgsParser(); 22 | new ArgsParser(new String[]{}); 23 | } 24 | 25 | @Test 26 | public void testConstructNull() { 27 | try { 28 | new ArgsParser(null); 29 | fail(); 30 | } catch (NullPointerException e) { 31 | } 32 | } 33 | 34 | @Test 35 | public void testGetArgs() { 36 | String[] args = new String[]{"aaa", "bbb", "ccc"}; 37 | ArgsParser parser = new ArgsParser(args); 38 | assertArrayEquals(args, parser.getArgs()); 39 | assertEquals(args.length, parser.getArgsCount()); 40 | assertEquals(args.length, parser.getArgsLeftCount()); 41 | } 42 | 43 | @Test 44 | public void testParseSwitchArgs() { 45 | String[] args = new String[]{"-a", "a", "--b", "icbc", "-cc", "cc", "--dd", "dd", "ee"}; 46 | ArgsParser parser = new ArgsParser(args); 47 | // short key 48 | assertTrue(parser.parseSwitchArgument("a").isSet()); 49 | assertTrue(parser.parseSwitchArgument("b").isSet()); 50 | assertFalse(parser.parseSwitchArgument("z").isSet()); 51 | // long key 52 | assertTrue(parser.parseSwitchArgument("dd").isSet()); 53 | assertFalse(parser.parseSwitchArgument("cc").isSet()); 54 | assertEquals(7, parser.getArgsLeftCount()); 55 | 56 | assertFalse(parser.parseSwitchArgument("-").isSet()); 57 | assertTrue(parser.parseSwitchArgument("c").isSet()); 58 | assertEquals(7, parser.getArgsLeftCount()); 59 | } 60 | 61 | @Test 62 | public void testParseParamArgsLong() { 63 | String[] args = new String[]{null, "--L116_3", "Hit!", "--L116_2", null, "--L116_1"}; 64 | ArgsParser parser = new ArgsParser(args); 65 | 66 | assertEquals(4, parser.getArgsLeftCount()); 67 | assertNull(parser.parseParameterArgument("zz")); 68 | assertEquals(4, parser.getArgsLeftCount()); 69 | 70 | assertNull(parser.parseParameterArgument("L116_1")); 71 | assertEquals(4, parser.getArgsLeftCount()); 72 | 73 | assertNull(parser.parseParameterArgument("L116_2")); 74 | assertEquals(4, parser.getArgsLeftCount()); 75 | 76 | ParameterArgument pa1 = parser.parseParameterArgument("L116_3"); 77 | assertNotNull(pa1); 78 | assertEquals("Hit!", pa1.getValue()); 79 | assertEquals(2, parser.getArgsLeftCount()); 80 | } 81 | 82 | @Test 83 | public void testParseParamArgsShort() { 84 | String[] args = new String[]{null, "z", "-e", "Hit!", null, "-uvw", "-xy", "--f", "-c", null, "-dHit!", "-b"}; 85 | ArgsParser parser = new ArgsParser(args); 86 | 87 | assertEquals(9, parser.getArgsLeftCount()); 88 | assertNull(parser.parseParameterArgument("z")); 89 | assertEquals(9, parser.getArgsLeftCount()); 90 | assertNull(parser.parseParameterArgument("b")); 91 | assertEquals(9, parser.getArgsLeftCount()); 92 | assertNull(parser.parseParameterArgument("c")); 93 | assertEquals(9, parser.getArgsLeftCount()); 94 | assertNull(parser.parseParameterArgument("f")); 95 | assertEquals(9, parser.getArgsLeftCount()); 96 | 97 | ParameterArgument pa1 = parser.parseParameterArgument("e"); 98 | assertNotNull(pa1); 99 | assertEquals("Hit!", pa1.getValue()); 100 | assertEquals(7, parser.getArgsLeftCount()); 101 | 102 | ParameterArgument pa2 = parser.parseParameterArgument("d"); 103 | assertNotNull(pa2); 104 | assertEquals("Hit!", pa2.getValue()); 105 | assertEquals(6, parser.getArgsLeftCount()); 106 | 107 | ParameterArgument pa3 = parser.parseParameterArgument("y"); 108 | assertNotNull(pa3); 109 | assertEquals("--f", pa3.getValue()); 110 | assertEquals(5, parser.getArgsLeftCount()); 111 | 112 | ParameterArgument pa4 = parser.parseParameterArgument("v"); 113 | assertNotNull(pa4); 114 | assertEquals("w", pa4.getValue()); 115 | assertEquals(5, parser.getArgsLeftCount()); 116 | 117 | assertNull(parser.parseParameterArgument("-")); 118 | } 119 | 120 | @Test 121 | public void testParseStringArgs() { 122 | String[] args = new String[]{null, "aaa", null, "bbb", null, "ccc"}; 123 | ArgsParser parser = new ArgsParser(args); 124 | 125 | assertEquals(3, parser.getArgsLeftCount()); 126 | List strs = parser.parseStringArgument(); 127 | assertEquals(3, strs.size()); 128 | assertEquals("aaa", strs.get(0).getValue()); 129 | assertEquals("bbb", strs.get(1).getValue()); 130 | assertEquals("ccc", strs.get(2).getValue()); 131 | assertEquals(0, parser.getArgsLeftCount()); 132 | } 133 | 134 | @Test 135 | public void testBoringClasses1() { 136 | Argument arg1 = new Argument(-2); 137 | Argument arg2 = new Argument(3); 138 | assertEquals(-2, arg1.getPosition()); 139 | assertEquals(3, arg2.getPosition()); 140 | assertEquals(-5, arg1.compareTo(arg2)); 141 | assertEquals(5, arg2.compareTo(arg1)); 142 | } 143 | 144 | @Test 145 | public void testBoringClasses2() { 146 | try { 147 | new ParameterArgument(0, "key", null); 148 | fail(); 149 | } catch (NullPointerException e) { 150 | } 151 | try { 152 | new ParameterArgument(0, null, "value"); 153 | fail(); 154 | } catch (NullPointerException e) { 155 | } 156 | try { 157 | new ParameterArgument(0, null, null); 158 | fail(); 159 | } catch (NullPointerException e) { 160 | } 161 | try { 162 | new ParameterArgument(0, "key", ""); 163 | fail(); 164 | } catch (IllegalArgumentException e) { 165 | } 166 | try { 167 | new ParameterArgument(0, "", "value"); 168 | fail(); 169 | } catch (IllegalArgumentException e) { 170 | } 171 | ParameterArgument pa = new ParameterArgument(741, "key", "value"); 172 | assertEquals(741, pa.getPosition()); 173 | assertEquals("key", pa.getKey()); 174 | assertEquals("value", pa.getValue()); 175 | 176 | assertTrue(new ParameterArgument(741, "key", "value").isLongKey()); 177 | assertFalse(new ParameterArgument(741, "k", "value").isLongKey()); 178 | } 179 | 180 | @Test 181 | public void testBoringClasses3() { 182 | try { 183 | new StringArgument(0, null); 184 | fail(); 185 | } catch (NullPointerException e) { 186 | } 187 | StringArgument sa = new StringArgument(741, ""); 188 | assertEquals(741, sa.getPosition()); 189 | assertEquals("", sa.getValue()); 190 | } 191 | 192 | @Test 193 | public void testExtra1() { 194 | String[] args = new String[]{"-"}; 195 | ArgsParser parser = new ArgsParser(args); 196 | try { 197 | parser.parseSwitchArgument(""); 198 | } catch (IllegalArgumentException e) { 199 | } 200 | assertEquals(1, parser.getArgsLeftCount()); 201 | } 202 | 203 | } 204 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/src/BPlusTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * B+ Tree 3 | * @author Lidan Hifi 4 | */ 5 | public class BPlusTree { 6 | // tree param 7 | private int t; 8 | // pointer to the root node. can be leaf or internal node. 9 | private Node root; 10 | // pointer to the first leaf in the tree, for kind-of InOrder scan. 11 | private LeafNode first; 12 | // the minimum gap between two elements in the tree. 13 | private int minGap; 14 | // pointer to a bloom filter object, for O(1) unsuccessful search. 15 | private IntegerBloomFilter filter = null; 16 | 17 | /* 18 | * Create new B+Tree 19 | * initialize a new root as an empty leaf 20 | * @param treeParam t that represents how many child nodes can an internal node have 21 | */ 22 | public BPlusTree(int treeParam) { 23 | t = treeParam; 24 | minGap = Integer.MAX_VALUE; 25 | root = new LeafNode(treeParam); 26 | first = (LeafNode)root; 27 | } 28 | 29 | /* 30 | * Create new B+Tree 31 | * @param treeParam t that represents how many child nodes can an internal node have 32 | * @param expectedNumberOfElements expected number of elements that will be stored in the tree. used for initialize the bloom filter, for O(1) unsucessful search. 33 | */ 34 | public BPlusTree(int treeParam, int expectedNumberOfElements) { 35 | this(treeParam); 36 | // initialize the bloom filter, with a false-positive probability of 0.000001 37 | filter = new IntegerBloomFilter(0.000001, expectedNumberOfElements); 38 | } 39 | 40 | /* 41 | * find the leaf that might store the given key 42 | * @param key the key that the search algorithm looking for 43 | * @return the leaf that might store the given key 44 | */ 45 | private LeafNode findLeaf(int key) { 46 | Node current = root; 47 | 48 | while (!(current instanceof LeafNode)) { 49 | current = ((InternalNode)current).getChildNode(key); 50 | } 51 | 52 | return (LeafNode)current; 53 | } 54 | 55 | /* 56 | * get the value for a given key, that is stored in the tree 57 | * @param key the value's key that was stored in the tree 58 | * @return Value if the search succeed, null if the key does not exist in the tree. 59 | */ 60 | public Value search(int key) { 61 | boolean continueToSearch = true; 62 | 63 | if (filter != null) // check if bloom filter was initialized 64 | continueToSearch = filter.contains(key); // find the given key in the filter 65 | 66 | if (continueToSearch) // if the bloom filter return true (it might happen when the key really exists, or either false positive) 67 | return findLeaf(key).getValue(key); 68 | else { 69 | System.out.println("Filter stopped the search."); 70 | System.out.println("Current False Positive Probability: " + filter.getCurrentFalsePositiveProbability()); 71 | } 72 | 73 | return null; 74 | } 75 | 76 | /* 77 | * Insert key,value to the tree. 78 | * @param key key for insertion 79 | * @param value value for insertion 80 | */ 81 | public void insert(int key, Value value) { 82 | // insert the data recursively, starting in the root 83 | InsertionResult result = root.insert(key, value); 84 | 85 | // the tree was split, create a new root that points to the split nodes 86 | if (result != null && result.getSplitRootKey() != null) 87 | root = new InternalNode(t, result); 88 | 89 | // update the min gap if the return min gap is smaller than the current one 90 | if (result != null && result.getMinGap() < minGap) 91 | minGap = result.getMinGap(); 92 | 93 | // if the bloom filter was initialized, add the given key to the filter for future search 94 | if (filter != null) 95 | filter.add(key); 96 | } 97 | 98 | /* 99 | * get string representation of the keys in descending order- from the last key to the first 100 | * @return string representation of the tree's keys in descending order 101 | */ 102 | public String reverseInOrder() { 103 | Node current = root; 104 | 105 | // find the right-most leaf 106 | while (!(current instanceof LeafNode)) { 107 | current = ((InternalNode)current).getMaxChildNode(); 108 | } 109 | 110 | LeafNode leaf = (LeafNode)current; 111 | StringBuilder sb = new StringBuilder(); 112 | 113 | // append to the result string the reversed elements in each leaf 114 | while (leaf != null) { 115 | sb.append(leaf.reverseToString()); 116 | leaf = leaf.getPrev(); 117 | } 118 | 119 | return sb.toString(); 120 | } 121 | 122 | /* 123 | * get the tree size- how many keys are stored 124 | */ 125 | public int getSize() { 126 | return root.getNodeSize(); 127 | } 128 | 129 | /* 130 | * get the minimum gap between any two keys in the tree 131 | * @return minimum gap value 132 | */ 133 | public int getMinGap() { 134 | return minGap; 135 | } 136 | 137 | /* 138 | * get the index of the given key in the tree 139 | * @return index of the given key if the key exists, -1 if the key does not exists 140 | */ 141 | public int order(int key) { 142 | int orderIndex = root.order(key); 143 | if (orderIndex != -1) // zero based 144 | return orderIndex + 1; 145 | 146 | return -1; 147 | } 148 | 149 | /* 150 | * get string representation of the keys in ascending order- from the first key to the last 151 | * @return string representation of the tree's keys in ascending order 152 | */ 153 | public String inOrder() { 154 | StringBuilder sb = new StringBuilder(); 155 | LeafNode current = first; 156 | 157 | // append the string representation of each leaf to the result string 158 | while (current != null) { 159 | sb.append(current); 160 | current = current.getNext(); 161 | } 162 | 163 | return sb.toString(); 164 | } 165 | 166 | /* 167 | * (non-Javadoc) 168 | * @see java.lang.Object#toString() 169 | */ 170 | public String toString() { 171 | if (root.getNodeSize() != 0) 172 | return root.toString(); 173 | 174 | return ""; 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/src/InsertionResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Represents a result of insertion operation. 3 | * always contains minGap- the minimum gap between the inserted key and his siblings. 4 | * may contains pointers to left & right nodes, if the node was split as a result of the insertion. 5 | * @author Lidan Hifi 6 | */ 7 | class InsertionResult { 8 | // new root after split 9 | private Integer splitRootKey; 10 | // pointers to the old node (left) and the new node (right) 11 | private Node left, right; 12 | // holds the minimum gap between the inserted key and his siblings 13 | private int minGap; 14 | 15 | /* 16 | * creates new insertion result, after split 17 | */ 18 | public InsertionResult(Integer key, Node left, Node right) { 19 | splitRootKey = key; 20 | this.left = left; 21 | this.right = right; 22 | } 23 | 24 | /* 25 | * creates new insertion result, with the minGap from the regular insertion (to a non-full node) 26 | */ 27 | public InsertionResult(Integer key, Node left, Node right, InsertionResult resultFromNonFullNode) { 28 | this(key, left, right); 29 | 30 | this.minGap = resultFromNonFullNode.getMinGap(); 31 | } 32 | 33 | /* 34 | * creates new insertion result, as a result from non-full node insertion (holds only the min gap) 35 | */ 36 | public InsertionResult(int minGap) { 37 | this(null, null, null); 38 | this.minGap = minGap; 39 | } 40 | 41 | public Node getLeftNode() { return left; } 42 | public Node getRightNode() { return right; } 43 | public Integer getSplitRootKey() { return splitRootKey; } 44 | public int getMinGap() { return minGap; } 45 | } 46 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/src/IntegerBloomFilter.java: -------------------------------------------------------------------------------- 1 | import java.util.BitSet; 2 | 3 | /* 4 | * Integer bloom filter- used for test whether an integer element is a member of a set or not. 5 | * @author Lidan Hifi 6 | */ 7 | public class IntegerBloomFilter { 8 | // filter set 9 | private BitSet bitset; 10 | // filter set size 11 | private final int bitSetSize; 12 | // bits per element that is stored in the structure 13 | private final int bitsPerElement; 14 | // expected elements to be added 15 | private final int expectedNumberOfElements; 16 | // total items actually added 17 | private int totalElements; 18 | // hash functions count 19 | private final int k; 20 | // hash params 21 | private final int hashParam1, hashParam2; 22 | 23 | /** 24 | * Constructs an empty Bloom filter. The total length of the Bloom filter will be 25 | * c*n. 26 | * 27 | * @param bitsPerElement is the number of bits used per element. 28 | * @param expectedNumberOfElements is the expected number of elements the filter will contain. 29 | * @param totalHashFunctions is the number of hash functions used. 30 | */ 31 | public IntegerBloomFilter(int bitsPerElement, int expectedNumberOfElements, int totalHashFunctions) { 32 | this.expectedNumberOfElements = expectedNumberOfElements; 33 | this.k = totalHashFunctions; 34 | this.bitsPerElement = bitsPerElement; 35 | this.bitSetSize = bitsPerElement * expectedNumberOfElements; 36 | totalElements = 0; 37 | this.bitset = new BitSet(bitSetSize); 38 | this.hashParam1 = (int)(Math.random() * 100); 39 | this.hashParam2 = (int)(Math.random() * 100); 40 | } 41 | 42 | /* 43 | * constructs a new Bloom Filter for a given false positive probability and expected number of elements 44 | * it is based on the formula -ln(p)/(ln2)^2 that represents how many bits we need per element, 45 | * and the formula -ln(p)/ln2 that represents how many hash functions we need. 46 | * @param falsePositiveProbability probability for false positive 47 | * @param expectedNumberOfElements is the expected number of elements the filter will contain. 48 | */ 49 | public IntegerBloomFilter(double falsePositiveProbability, int expectedNumberOfElements) { 50 | this((int)Math.ceil(-(Math.log(falsePositiveProbability) / (Math.log(2) * Math.log(2)))), expectedNumberOfElements, (int)Math.ceil(-(Math.log(falsePositiveProbability)) / Math.log(2))); 51 | } 52 | 53 | /* 54 | * get the expected false positive probability, based on the expected number of elements that configured on initialization. 55 | * this probability is constant during the filter's life. 56 | * @return the expected false positive probability 57 | */ 58 | public double getExpectedFalsePositiveProbability() { 59 | return getFalsePositiveProbability(expectedNumberOfElements); 60 | } 61 | 62 | /* 63 | * get the expected false positive probability, based on the given number of elements 64 | * @return the expected false positive probability for the given number of elements 65 | */ 66 | public double getFalsePositiveProbability(double elementsNumber) { 67 | return Math.pow(1 - Math.exp(-k * (double)elementsNumber / (double)bitSetSize), k); 68 | } 69 | 70 | /* 71 | * get the current false positive probability, based on the total number of elements that actually added to the filter 72 | * this probability is variable during the filter's life, and increases each time an element is added 73 | * @return the current false positive probability 74 | */ 75 | public double getCurrentFalsePositiveProbability() { 76 | return getFalsePositiveProbability(totalElements); 77 | } 78 | 79 | /* 80 | * clear the filter 81 | */ 82 | public void clear() { 83 | bitset.clear(); 84 | totalElements = 0; 85 | } 86 | 87 | /* 88 | * calculates the hash functions (it generates the function based on the hash params that configured randomly in the filter initialization 89 | * @param data the given key for calculation 90 | * @param hashes how many hash functions is needed to be calculated 91 | * @return integer array that contains the results of the functions. need to operate mod function on each result, based on the filter set size. 92 | */ 93 | private int[] createHashes(int data, int hashes) { 94 | int[] hashValues = new int[hashes]; 95 | 96 | for (int i = 0; i < hashes; i++) { 97 | hashValues[i] = ((i + hashParam1) * data + hashParam2) % 701; 98 | } 99 | 100 | return hashValues; 101 | } 102 | 103 | /* 104 | * add an element to the filter 105 | * @param element the given element for insertion 106 | */ 107 | public void add(int element) { 108 | int[] hashes = createHashes(element, k); 109 | 110 | for (int hash : hashes) 111 | bitset.set(Math.abs(hash % bitSetSize), true); 112 | 113 | totalElements++; 114 | } 115 | 116 | /* 117 | * test whether the given element is in the set or not 118 | * @param element the given element for query 119 | * @return true if the given element may be in the set (or maybe false positive), false if not (and it is 100% not). 120 | */ 121 | public boolean contains(int element) { 122 | int[] hashes = createHashes(element, k); 123 | 124 | for (int hash : hashes) { 125 | if (!bitset.get(Math.abs(hash % bitSetSize))) 126 | return false; 127 | } 128 | 129 | return true; 130 | } 131 | 132 | /* 133 | * get how many bits in the filter represents an element in the set 134 | * @return bits per element 135 | */ 136 | public int getBitsPerElement() { 137 | return bitsPerElement; 138 | } 139 | 140 | /* 141 | * get the filter set size 142 | * @return the filter set size 143 | */ 144 | public int getFilterSize() { 145 | return bitSetSize; 146 | } 147 | 148 | /* 149 | * get the total hash functions of the filter 150 | * @return the total hash function of the filter 151 | */ 152 | public int getTotalHashFunctions() { 153 | return k; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/src/LeafNode.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | /* 5 | * Represents an internal node in the B+Tree 6 | * @author Lidan Hifi 7 | */ 8 | class LeafNode extends Node { 9 | // values vector (each index in the keys vector is matching another index in the values vector) 10 | private List values; 11 | // pointers to the next leaf and the previous leaf 12 | private LeafNode next; 13 | private LeafNode prev; 14 | 15 | /* 16 | * creates new leaf node 17 | * @param totalKeys tree param 18 | */ 19 | public LeafNode(int totalKeys) { 20 | super(totalKeys); 21 | values = new ArrayList(t - 1); 22 | } 23 | 24 | /* 25 | * creates new leaf node split from a previous leaf node 26 | * @param totalKeys tree param 27 | * @param prev previous leaf 28 | */ 29 | public LeafNode(int totalKeys, LeafNode prev) { 30 | this(totalKeys); 31 | this.prev = prev; 32 | this.next = prev.next; 33 | if (this.next != null) 34 | this.next.prev = this; 35 | 36 | prev.next = this; 37 | } 38 | 39 | /* 40 | * creates new leaf node split from a previous leaf node, with a given keys and values 41 | * @param totalKeys tree param 42 | * @param prev previous leaf 43 | * @param keys keys list 44 | * @param values values list 45 | */ 46 | public LeafNode(int totalKeys, LeafNode prev, List keys, List values) { 47 | this(totalKeys, prev); 48 | this.keys.addAll(keys); 49 | this.values.addAll(values); 50 | } 51 | 52 | /* 53 | * (non-Javadoc) 54 | * @see data.Node#order(int) 55 | */ 56 | public int order(int key) { 57 | return keys.indexOf(key); 58 | } 59 | 60 | /* 61 | * get the value that matches a given key 62 | * @param key key for searching 63 | * @return value if the key was found, null if not 64 | */ 65 | public Value getValue(int key) { 66 | // find the index of the given key 67 | int index = order(key); 68 | 69 | // if the index was found, return the matched value 70 | if (index != -1) 71 | return values.get(index); 72 | else 73 | return null; 74 | } 75 | 76 | /* 77 | * insert key,value to a non-full leaf node 78 | * @param key key 79 | * @param value value 80 | */ 81 | private InsertionResult insertNonFull(int key, Value value) { 82 | return insertNonFull(key, value, findLessThanOrEqualToKey(key)); 83 | } 84 | 85 | /* 86 | * insert key,value to a non-full leaf node 87 | * @param key key 88 | * @param value value 89 | */ 90 | private InsertionResult insertNonFull(int key, Value value, int index) { 91 | if (keys.isEmpty() || (index == keys.size() - 1 && keys.get(index).compareTo(key) < 0)) { 92 | // keys list is empty or insert as right most 93 | keys.add(key); 94 | values.add(value); 95 | } else { 96 | // insert in the middle of the list 97 | keys.add(index, key); 98 | values.add(index, value); 99 | } 100 | 101 | // return insertion result that contains the minimum gap between the given key and his siblings 102 | return new InsertionResult(calculateGap(index)); 103 | } 104 | 105 | /* 106 | * (non-Javadoc) 107 | * @see data.Node#insert(int, java.lang.Object) 108 | */ 109 | public InsertionResult insert(int key, Value value) { 110 | // find the index for insertion 111 | int indexForInsertion = findLessThanOrEqualToKey(key); 112 | InsertionResult resultFromNonFullInsertion = null; 113 | 114 | if (indexForInsertion != -1 && indexForInsertion < keys.size() && keys.get(indexForInsertion).equals(key)) { 115 | // duplicate value, simply overwrite the old one 116 | values.set(indexForInsertion, value); 117 | } else if (keys.size() < t - 1) { 118 | // if node is not full- insert non full and return insertion result that contains the minimum gap 119 | resultFromNonFullInsertion = insertNonFull(key, value, indexForInsertion); 120 | } else { 121 | // if the leaf is full- SPLIT the keys and the values 122 | LeafNode nextSibling; 123 | int mid = 0; 124 | if (t % 2 == 0) { 125 | mid = keys.size() / 2; 126 | } else { 127 | mid = (keys.size() + 1) / 2; 128 | } 129 | 130 | // move keys & values to the next node, and make insertion- based on the original index and the mid 131 | if (indexForInsertion <= mid) { 132 | // insert the new key to the current leaf 133 | nextSibling = new LeafNode(t, this, this.keys.subList(mid, this.keys.size()), this.values.subList(mid, this.values.size())); 134 | this.keys = new ArrayList(this.keys.subList(0, mid)); 135 | this.values = new ArrayList(this.values.subList(0, mid)); 136 | 137 | resultFromNonFullInsertion = insertNonFull(key, value); 138 | } else { 139 | // insert the new key to the new sibling 140 | nextSibling = new LeafNode(t, this, this.keys.subList(mid + 1, this.keys.size()), this.values.subList(mid + 1, this.values.size())); 141 | this.keys = new ArrayList(this.keys.subList(0, mid + 1)); 142 | this.values = new ArrayList(this.values.subList(0, mid + 1)); 143 | 144 | resultFromNonFullInsertion = nextSibling.insertNonFull(key, value); 145 | } 146 | 147 | // return new insertion result, contains the minimum gap and the split (right, left and new root) 148 | return new InsertionResult(this.keys.get(this.keys.size() - 1), this, nextSibling, resultFromNonFullInsertion); 149 | } 150 | 151 | return resultFromNonFullInsertion; 152 | } 153 | 154 | /* 155 | * calculates the gap between the key in the given index, and his siblings 156 | * @param index index of the inserted key 157 | * @return the minimum gap between the right gap and the left gap 158 | */ 159 | protected int calculateGap(int index) { 160 | // initialize the init gaps to infinity 161 | int leftGap = Integer.MAX_VALUE, rightGap = Integer.MAX_VALUE; 162 | 163 | if (index >= 0) { 164 | // rightGap 165 | Integer nextKey = null; 166 | if (index + 1 < keys.size()) // inside the node 167 | nextKey = keys.get(index + 1); 168 | else if (next != null) // calculate with the first element of the next node 169 | nextKey = next.keys.get(0); 170 | 171 | if (nextKey != null) 172 | rightGap = Math.abs( (Integer)keys.get(index) - (Integer)nextKey ); 173 | 174 | // leftGap 175 | Integer prevKey = null; 176 | if (index - 1 >= 0) 177 | prevKey = keys.get(index - 1); // inside the node 178 | else if (prev != null) 179 | prevKey = prev.keys.get(prev.keys.size() - 1); // calculate with the last element of the previous node 180 | 181 | if (prevKey != null) 182 | leftGap = Math.abs( (Integer)keys.get(index) - (Integer)prevKey ); 183 | } 184 | 185 | return Math.min(rightGap, leftGap); 186 | } 187 | 188 | /* 189 | * get the next leaf 190 | * @return next leaf 191 | */ 192 | public LeafNode getNext() { 193 | return this.next; 194 | } 195 | 196 | /* 197 | * get the previous leaf 198 | * @return previous leaf 199 | */ 200 | public LeafNode getPrev() { 201 | return this.prev; 202 | } 203 | 204 | /* 205 | * get string representation of the keys in descending order- from the last key to the first 206 | * @return string representation of the leaf's keys in descending order 207 | */ 208 | public String reverseToString() { 209 | StringBuilder sb = new StringBuilder(); 210 | 211 | for (int i = this.keys.size() - 1; i >= 0; i--) { 212 | sb.append(this.keys.get(i) + ","); 213 | } 214 | 215 | return sb.toString().substring(0, sb.toString().length()); 216 | } 217 | 218 | /* 219 | * get string representation of the keys in ascending order- from the first key to the last 220 | * @return string representation of the leaf's keys in ascending order 221 | */ 222 | public String toString() { 223 | StringBuilder sb = new StringBuilder(); 224 | 225 | for (int i = 0; i < this.keys.size() - 1; i++) { 226 | sb.append(this.keys.get(i) + ","); 227 | } 228 | sb.append(this.keys.get(this.keys.size() - 1)); 229 | 230 | return sb.toString(); 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/src/Node.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | /* 5 | * Represents a node in the B+Tree 6 | * @author Lidan Hifi 7 | */ 8 | abstract class Node { 9 | protected int t; // tree param 10 | protected List keys; 11 | 12 | /* 13 | * creates new node, and initialize the keys vector to (t-1) initial capacity 14 | * @param totalKeys tree param 15 | */ 16 | Node(int totalKeys) { 17 | t = totalKeys; 18 | keys = new ArrayList(t - 1); 19 | } 20 | 21 | /* 22 | * Insert a key & value to the node. 23 | * @param key key for insertion 24 | * @param value object for insertion (can be integer or string for example, or any class that inherit from Object) 25 | * @return insertion result - an object that contains the minimum gap between the inserted key and his siblings keys, 26 | * and if the node was split in two parts- contains the new root and pointers to the right node (new one) and left node (old one) 27 | */ 28 | public abstract InsertionResult insert(int key, Value value); 29 | 30 | /* 31 | * get the index of the given key in the tree rooted at this node 32 | * @param key the given key for searching 33 | * @return the index of the given key in the tree rooted at this node (or in the keys vector if it is leaf) 34 | */ 35 | public abstract int order(int key); 36 | 37 | /* 38 | * get the node size- how many keys are stored in 39 | * @return the keys vector size 40 | */ 41 | public int getNodeSize() { 42 | return keys.size(); 43 | } 44 | 45 | /* 46 | * get the index of the key that equals to the given key, or the last key that less than the given key 47 | * used in variant of binary search to find the index 48 | * @param key the given key for searching 49 | * @result index of the key that less than or equal to the given key 50 | */ 51 | protected int findLessThanOrEqualToKey(int key) { 52 | // check the right most key 53 | // in this case, when the given key is bigger than any other key, 54 | // the algorithm complexity will be O(1) 55 | if (keys.size() > 0 && keys.get(keys.size() - 1).compareTo(key) < 0) 56 | return keys.size(); 57 | // check the left most key 58 | // in this case, when the given key is smaller than any other key, 59 | // the algorithm complexity will be O(1) 60 | else if (keys.size() > 0 && keys.get(0).compareTo(key) >= 0) 61 | return 0; 62 | else { 63 | // find the index by a kind-of binary search 64 | int from = 0; 65 | int to = keys.size() - 1; 66 | 67 | while (from <= to) { 68 | int mid = (from + to) / 2; 69 | 70 | if (mid < keys.size() - 1 && keys.get(mid).compareTo(key) < 0 && keys.get(mid + 1).compareTo(key) > 0) 71 | return mid + 1; 72 | else if (keys.get(mid).compareTo(key) > 0) 73 | to = mid - 1; 74 | else if (keys.get(mid).compareTo(key) < 0) 75 | from = mid + 1; 76 | else 77 | return mid; 78 | } 79 | } 80 | 81 | return -1; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/test/BPlusTreeTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | import java.io.PrintStream; 8 | import java.lang.reflect.Field; 9 | import java.util.BitSet; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | public class BPlusTreeTest { 14 | 15 | private BPlusTree tree; 16 | 17 | private BPlusTree tree2; 18 | 19 | @Test 20 | public void test1() throws IOException { 21 | BPlusTree tree = new BPlusTree<>(3, 5); 22 | BPlusTree tree2 = new BPlusTree<>(3); 23 | tree.insert(35, 1); 24 | tree.insert(35, 2); 25 | tree.insert(78, 3); 26 | tree.insert(12, 4); 27 | tree.insert(54, 5); 28 | tree2.insert(35, 1); 29 | tree2.insert(35, 2); 30 | tree2.insert(78, 3); 31 | tree2.insert(12, 4); 32 | tree2.insert(54, 5); 33 | 34 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 35 | PrintStream ps = new PrintStream(os); 36 | System.setOut(ps); 37 | 38 | assertEquals("", new BPlusTree<>(3).toString()); 39 | assertEquals("12,35#54,78", tree.toString()); 40 | assertEquals("12,3554,78", tree.inOrder()); 41 | assertEquals("78,54,35,12,", tree.reverseInOrder()); 42 | 43 | assertEquals(2, tree.search(35).intValue()); 44 | assertEquals(3, tree.search(78).intValue()); 45 | assertEquals(4, tree.search(12).intValue()); 46 | assertEquals(5, tree.search(54).intValue()); 47 | assertNull(tree.search(55)); 48 | 49 | assertEquals(2, tree2.search(35).intValue()); 50 | assertEquals(3, tree2.search(78).intValue()); 51 | assertEquals(4, tree2.search(12).intValue()); 52 | assertEquals(5, tree2.search(54).intValue()); 53 | assertNull(tree2.search(55)); 54 | 55 | assertEquals(2, tree.order(35)); 56 | assertEquals(4, tree.order(78)); 57 | assertEquals(1, tree.order(12)); 58 | assertEquals(3, tree.order(54)); 59 | assertEquals(-1, tree.order(55)); 60 | 61 | assertEquals(4, tree.getSize()); 62 | assertEquals(19, tree.getMinGap()); 63 | 64 | assertTrue(os.toString().contains("Filter stopped the search.")); 65 | assertTrue(os.toString().contains("Current False Positive Probability: 8.89124548750276E-7")); 66 | } 67 | 68 | @Test 69 | public void test2() { 70 | BPlusTree tree = new BPlusTree<>(4, 100); 71 | BPlusTree tree2 = new BPlusTree<>(3, 100); 72 | for (int i = 50; i >= 1; i--) { 73 | tree.insert(i, i * 3); 74 | tree2.insert(i, i * 3); 75 | } 76 | for (int i = 51; i <= 100; i++) { 77 | tree.insert(i, i * 2); 78 | tree2.insert(i, i * 2); 79 | } 80 | for (int i = 1; i <= 50; i++) { 81 | assertEquals(i * 3, tree.search(i).intValue()); 82 | assertEquals(i * 3, tree2.search(i).intValue()); 83 | } 84 | for (int i = 51; i <= 100; i++) { 85 | assertEquals(i * 2, tree.search(i).intValue()); 86 | assertEquals(i * 2, tree2.search(i).intValue()); 87 | } 88 | } 89 | 90 | @Test 91 | public void testIntBF() throws IllegalAccessException, NoSuchFieldException { 92 | IntegerBloomFilter bf1 = new IntegerBloomFilter(7, 4, 3); 93 | assertEquals(7, bf1.getBitsPerElement()); 94 | assertEquals(28, bf1.getFilterSize()); 95 | assertEquals(3, bf1.getTotalHashFunctions()); 96 | assertEquals(0.042348, bf1.getExpectedFalsePositiveProbability(), 1E-6); 97 | assertEquals(0.0, bf1.getCurrentFalsePositiveProbability(), 1E-6); 98 | 99 | Field bs = IntegerBloomFilter.class.getDeclaredField("bitset"); 100 | bs.setAccessible(true); 101 | bf1.add(1); 102 | assertFalse(((BitSet) bs.get(bf1)).isEmpty()); 103 | bf1.clear(); 104 | assertTrue(((BitSet) bs.get(bf1)).isEmpty()); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /JUnit/BPlusTree/test/InsertionResult_ESTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | import static org.junit.Assert.fail; 7 | 8 | public class InsertionResult_ESTest { 9 | 10 | @Test(timeout = 4000) 11 | public void test00() throws Throwable { 12 | Integer integer0 = new Integer(0); 13 | InsertionResult insertionResult0 = new InsertionResult(integer0, (Node) null, (Node) null); 14 | Integer integer1 = insertionResult0.getSplitRootKey(); 15 | assertEquals(0, (int) integer1); 16 | } 17 | 18 | @Test(timeout = 4000) 19 | public void test01() throws Throwable { 20 | Integer integer0 = new Integer(1905); 21 | LeafNode leafNode0 = new LeafNode(663); 22 | InsertionResult insertionResult0 = new InsertionResult(integer0, leafNode0, leafNode0); 23 | Integer integer1 = insertionResult0.getSplitRootKey(); 24 | assertEquals(1905, (int) integer1); 25 | } 26 | 27 | @Test(timeout = 4000) 28 | public void test02() throws Throwable { 29 | Integer integer0 = new Integer((-5227)); 30 | InsertionResult insertionResult0 = new InsertionResult(integer0, (Node) null, (Node) null); 31 | Integer integer1 = insertionResult0.getSplitRootKey(); 32 | assertEquals((-5227), (int) integer1); 33 | } 34 | 35 | @Test(timeout = 4000) 36 | public void test03() throws Throwable { 37 | Integer integer0 = new Integer(2303); 38 | LeafNode leafNode0 = new LeafNode(1382); 39 | InsertionResult insertionResult0 = new InsertionResult(2); 40 | InsertionResult insertionResult1 = new InsertionResult(integer0, leafNode0, leafNode0, insertionResult0); 41 | insertionResult1.getRightNode(); 42 | assertEquals(2, insertionResult0.getMinGap()); 43 | assertEquals(2, insertionResult1.getMinGap()); 44 | } 45 | 46 | @Test(timeout = 4000) 47 | public void test04() throws Throwable { 48 | Integer integer0 = new Integer(2); 49 | LeafNode leafNode0 = new LeafNode(1); 50 | InsertionResult insertionResult0 = new InsertionResult(integer0, leafNode0, leafNode0); 51 | InternalNode internalNode0 = new InternalNode(2, insertionResult0); 52 | InsertionResult insertionResult1 = internalNode0.insert(0, (String) null); 53 | Node node0 = insertionResult1.getRightNode(); 54 | assertEquals(2, node0.getNodeSize()); 55 | assertEquals(Integer.MAX_VALUE, insertionResult1.getMinGap()); 56 | } 57 | 58 | @Test(timeout = 4000) 59 | public void test05() throws Throwable { 60 | InsertionResult insertionResult0 = new InsertionResult(0); 61 | int int0 = insertionResult0.getMinGap(); 62 | assertEquals(0, int0); 63 | } 64 | 65 | @Test(timeout = 4000) 66 | public void test06() throws Throwable { 67 | InsertionResult insertionResult0 = new InsertionResult(1192); 68 | int int0 = insertionResult0.getMinGap(); 69 | assertEquals(1192, int0); 70 | } 71 | 72 | @Test(timeout = 4000) 73 | public void test07() throws Throwable { 74 | InsertionResult insertionResult0 = new InsertionResult((-5227)); 75 | insertionResult0.getLeftNode(); 76 | assertEquals((-5227), insertionResult0.getMinGap()); 77 | } 78 | 79 | @Test(timeout = 4000) 80 | public void test08() throws Throwable { 81 | Integer integer0 = new Integer(1); 82 | LeafNode leafNode0 = new LeafNode(1); 83 | InternalNode internalNode0 = new InternalNode(1); 84 | InsertionResult insertionResult0 = new InsertionResult(integer0, leafNode0, internalNode0); 85 | InternalNode internalNode1 = new InternalNode(1, insertionResult0); 86 | InsertionResult insertionResult1 = internalNode1.insert((-1), "/^Wk"); 87 | insertionResult1.getLeftNode(); 88 | assertEquals(Integer.MAX_VALUE, insertionResult1.getMinGap()); 89 | } 90 | 91 | @Test(timeout = 4000) 92 | public void test09() throws Throwable { 93 | Integer integer0 = new Integer(4473); 94 | InsertionResult insertionResult0 = null; 95 | try { 96 | insertionResult0 = new InsertionResult(integer0, (Node) null, (Node) null, (InsertionResult) null); 97 | fail("Expecting exception: NullPointerException"); 98 | 99 | } catch (NullPointerException e) { 100 | // 101 | // no message in exception (getMessage() returned null) 102 | // 103 | // verifyException("net.mooctest.InsertionResult", e); 104 | } 105 | } 106 | 107 | @Test(timeout = 4000) 108 | public void test10() throws Throwable { 109 | InsertionResult insertionResult0 = new InsertionResult((-5227)); 110 | insertionResult0.getRightNode(); 111 | assertEquals((-5227), insertionResult0.getMinGap()); 112 | } 113 | 114 | @Test(timeout = 4000) 115 | public void test11() throws Throwable { 116 | InsertionResult insertionResult0 = new InsertionResult((-5227)); 117 | int int0 = insertionResult0.getMinGap(); 118 | assertEquals((-5227), int0); 119 | } 120 | 121 | @Test(timeout = 4000) 122 | public void test12() throws Throwable { 123 | InsertionResult insertionResult0 = new InsertionResult((-5227)); 124 | insertionResult0.getSplitRootKey(); 125 | assertEquals((-5227), insertionResult0.getMinGap()); 126 | } 127 | 128 | @Test(timeout = 4000) 129 | public void test13() throws Throwable { 130 | Integer integer0 = new Integer(1); 131 | LeafNode leafNode0 = new LeafNode(1); 132 | InternalNode internalNode0 = new InternalNode(1); 133 | InsertionResult insertionResult0 = new InsertionResult(integer0, leafNode0, internalNode0); 134 | Node node0 = insertionResult0.getLeftNode(); 135 | assertEquals(0, node0.getNodeSize()); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/main/java/net/mooctest/BrainfuckEngine.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Fabian M. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.mooctest; 17 | 18 | import java.io.BufferedReader; 19 | import java.io.File; 20 | import java.io.FileReader; 21 | import java.io.InputStream; 22 | import java.io.InputStreamReader; 23 | import java.io.OutputStream; 24 | import java.io.PrintStream; 25 | 26 | /** 27 | * The {@link BrainfuckEngine} class is an implementation of the original brainfuck 28 | * language. 29 | * 30 | * @author Fabian M. 31 | */ 32 | public class BrainfuckEngine { 33 | 34 | /** 35 | * The memory thats available for this brainfuck program. 36 | */ 37 | protected byte[] data; 38 | 39 | /** 40 | * The data pointer that points to the current index in the {@link BrainfuckEngine#data} memory array. 41 | */ 42 | protected int dataPointer = 0; 43 | 44 | /** 45 | * The character pointer that points to the current index of the character array 46 | * of value of its file or string. 47 | */ 48 | protected int charPointer = 0; 49 | 50 | /** 51 | * The {@link BrainfuckEngine#fileReader} allows use to read from a file if one is specified. 52 | */ 53 | protected BufferedReader fileReader; 54 | 55 | /** 56 | * The {@link BrainfuckEngine#consoleReader} allows us to read from the console for the ',' keyword. 57 | */ 58 | protected InputStreamReader consoleReader; 59 | 60 | /** 61 | * The {@link BrainfuckEngine#outWriter} allows us to write to the console. 62 | */ 63 | protected OutputStream outWriter; 64 | 65 | /** 66 | * The current line the engine is at. 67 | */ 68 | protected int lineCount = 0; 69 | 70 | /** 71 | * The current column the engine is at. 72 | */ 73 | protected int columnCount = 0; 74 | 75 | /** 76 | * The {@link Token} class contains tokens in brainfuck. 77 | * 78 | * @author Fabian M. 79 | */ 80 | protected static class Token { 81 | public final static char NEXT = '>'; 82 | public final static char PREVIOUS = '<'; 83 | public final static char PLUS = '+'; 84 | public final static char MINUS = '-'; 85 | public final static char OUTPUT = '.'; 86 | public final static char INPUT = ','; 87 | public final static char BRACKET_LEFT = '['; 88 | public final static char BRACKET_RIGHT = ']'; 89 | } 90 | 91 | /** 92 | * Constructs a new {@link BrainfuckEngine} instance. 93 | * 94 | * @param cells 95 | * The amount of memory cells. 96 | */ 97 | public BrainfuckEngine(int cells) { 98 | this(cells, new PrintStream(System.out), System.in); 99 | } 100 | 101 | /** 102 | * Constructs a new {@link BrainfuckEngine} instance. 103 | * 104 | * @param cells 105 | * The amount of memory cells. 106 | * @param out The outputstream of this program. 107 | */ 108 | public BrainfuckEngine(int cells, OutputStream out) { 109 | this(cells, out, System.in); 110 | } 111 | 112 | /** 113 | * Constructs a new {@link BrainfuckEngine} instance. 114 | * 115 | * @param cells 116 | * The amount of memory cells. 117 | * @param out The printstream of this program. 118 | * @param in The outputstream of this program. 119 | */ 120 | public BrainfuckEngine(int cells, OutputStream out, InputStream in) { 121 | initate(cells); 122 | outWriter = out; 123 | consoleReader = new InputStreamReader(in); 124 | } 125 | 126 | /** 127 | * Initiate this instance. 128 | */ 129 | protected void initate(int cells) { 130 | data = new byte[cells]; 131 | dataPointer = 0; 132 | charPointer = 0; 133 | } 134 | 135 | /** 136 | * Interprets the given file. 137 | * 138 | * @param file 139 | * The file to interpret. 140 | * @throws Exception 141 | */ 142 | public void interpret(File file) throws Exception { 143 | fileReader = new BufferedReader(new FileReader(file)); 144 | String content = ""; 145 | String line = ""; 146 | while((line = fileReader.readLine()) != null) { 147 | content += line; 148 | lineCount++; 149 | } 150 | interpret(content); 151 | } 152 | 153 | /** 154 | * Interprets the given string. 155 | * 156 | * @param str 157 | * The string to interpret. 158 | * @throws Exception 159 | */ 160 | public void interpret(String str) throws Exception { 161 | for (; charPointer < str.length(); charPointer++) 162 | interpret(str.charAt(charPointer), str.toCharArray()); 163 | initate(data.length); 164 | } 165 | 166 | /** 167 | * Interprets the given char 168 | * 169 | * @param c 170 | * The char to interpret. 171 | * @throws Exception 172 | */ 173 | protected void interpret(char c, char[] chars) throws Exception { 174 | switch (c) { 175 | case Token.NEXT: 176 | // Increment the data pointer (to point to the next cell to the right). 177 | if ((dataPointer + 1) > data.length) { 178 | throw new Exception("Error on line " + lineCount + ", column " + columnCount + ":" 179 | + "data pointer (" + dataPointer 180 | + ") on postion " + charPointer + "" + " out of range."); 181 | } 182 | dataPointer++; 183 | break; 184 | case Token.PREVIOUS: 185 | // Decrement the data pointer (to point to the next cell to the left). 186 | if ((dataPointer - 1) < 0) { 187 | throw new Exception("Error on line " + lineCount + ", column " + columnCount + ":" 188 | + "data pointer (" + dataPointer 189 | + ") on postion " + charPointer + " " + "negative."); 190 | } 191 | dataPointer--; 192 | break; 193 | case Token.PLUS: 194 | // Increment (increase by one) the byte at the data pointer. 195 | /*if ((((int) data[dataPointer]) + 1) > Integer.MAX_VALUE) { 196 | throw new Exception("Error on line " + lineCount + ", column " + columnCount + ":" 197 | + "byte value at data pointer (" 198 | + dataPointer + ") " + " on postion " + charPointer 199 | + " higher than byte max value."); 200 | }*/ 201 | data[dataPointer]++; 202 | break; 203 | case Token.MINUS: 204 | // Decrement (decrease by one) the byte at the data pointer. 205 | /*if ((data[dataPointer] - 1) < 0) { 206 | throw new Exception("Error on line " + lineCount + ", column " + columnCount + ":" 207 | + "at data pointer " + dataPointer 208 | + " on postion " + charPointer 209 | + ": Value can not be lower than zero."); 210 | }*/ 211 | data[dataPointer]--; 212 | break; 213 | case Token.OUTPUT: 214 | // Output the byte at the current index in a character. 215 | outWriter.write((char) data[dataPointer]); 216 | break; 217 | case Token.INPUT: 218 | // Accept one byte of input, storing its value in the byte at the data pointer. 219 | data[dataPointer] = (byte) consoleReader.read(); 220 | break; 221 | case Token.BRACKET_LEFT: 222 | if (data[dataPointer] == 0) { 223 | int i = 1; 224 | while (i > 0) { 225 | char c2 = chars[++charPointer]; 226 | if (c2 == Token.BRACKET_LEFT) 227 | i++; 228 | else if (c2 == Token.BRACKET_RIGHT) 229 | i--; 230 | } 231 | } 232 | break; 233 | case Token.BRACKET_RIGHT: 234 | int i = 1; 235 | while (i > 0) { 236 | char c2 = chars[--charPointer]; 237 | if (c2 == Token.BRACKET_LEFT) 238 | i--; 239 | else if (c2 == Token.BRACKET_RIGHT) 240 | i++; 241 | } 242 | charPointer--; 243 | break; 244 | } 245 | columnCount++; 246 | } 247 | } 248 | -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/main/java/net/mooctest/OokEngine.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Fabian M. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.mooctest; 17 | 18 | import java.io.InputStream; 19 | import java.io.OutputStream; 20 | import java.io.PrintStream; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * The {@link OokEngine} is an implementation for the 26 | * brainfuck derivative Ook!. 27 | * 28 | * @author Fabian M. 29 | */ 30 | public class OokEngine extends TrollScriptEngine { 31 | 32 | /** 33 | * The default length of a token. 34 | */ 35 | protected int defaultTokenLength = 9; 36 | 37 | /** 38 | * The {@link Token} enum contains tokens of Ook!. 39 | * 40 | * @author Fabian M. 41 | */ 42 | protected static enum Token { 43 | NEXT("Ook. Ook?"), 44 | PREVIOUS("Ook? Ook."), 45 | PLUS("Ook. Ook."), 46 | MINUS("Ook! Ook!"), 47 | OUTPUT("Ook! Ook."), 48 | INPUT("Ook. Ook!"), 49 | BRACKET_LEFT("Ook! Ook?"), 50 | BRACKET_RIGHT("Ook? Ook!"); 51 | 52 | String value; 53 | 54 | /** 55 | * Constructs a new token. 56 | * 57 | * @param value The value of the token. 58 | */ 59 | Token(String value) { 60 | this.value = value; 61 | } 62 | 63 | /** 64 | * Get the value of the token. 65 | * 66 | * @return the value. 67 | */ 68 | public String getValue() { 69 | return value; 70 | } 71 | } 72 | 73 | /** 74 | * Constructs a new {@link OokEngine} instance. 75 | * 76 | * @param cells 77 | * The amount of memory cells. 78 | */ 79 | public OokEngine(int cells) { 80 | this(cells, new PrintStream(System.out), System.in); 81 | } 82 | 83 | /** 84 | * Constructs a new {@link OokEngine} instance. 85 | * 86 | * @param cells 87 | * The amount of memory cells. 88 | * @param out 89 | * The outputstream of this program. 90 | */ 91 | public OokEngine(int cells, OutputStream out) { 92 | this(cells, out, System.in); 93 | } 94 | 95 | /** 96 | * Constructs a new {@link OokEngine} instance. 97 | * 98 | * @param cells 99 | * The amount of memory cells. 100 | * @param out 101 | * The printstream of this program. 102 | * @param in 103 | * The outputstream of this program. 104 | */ 105 | public OokEngine(int cells, OutputStream out, InputStream in) { 106 | super(cells, out, in); 107 | } 108 | 109 | /** 110 | * Interprets the given string. 111 | * 112 | * @param str 113 | * The string to interpret. 114 | * @throws Exception 115 | */ 116 | @Override 117 | public void interpret(String str) throws Exception { 118 | // List with tokens.defaultTokenLenght 119 | List tokens = new ArrayList(); 120 | // It fine that all Ook! tokens are 9 characters long :) 121 | // So we aren't going to loop through all characters.. 122 | for (; charPointer < str.length(); ) { 123 | String token = ""; 124 | if (charPointer + defaultTokenLength <= str.length()) 125 | // The string we found. 126 | token = str.substring(charPointer, charPointer + defaultTokenLength); 127 | else 128 | token = str.substring(charPointer, charPointer 129 | + (str.length() - charPointer)); 130 | 131 | boolean b = false; 132 | 133 | for (Token tokenCheck : Token.values()) { 134 | if (tokenCheck.getValue().equals(token)) { 135 | tokens.add(tokenCheck); 136 | charPointer += defaultTokenLength; 137 | b = true; 138 | break; 139 | } 140 | } 141 | 142 | // If the token was invalid, b is false. 143 | if (!b) 144 | if (charPointer + defaultTokenLength > str.length()) 145 | charPointer += (str.length() - charPointer); 146 | else 147 | charPointer++; 148 | 149 | 150 | } 151 | 152 | // Loop through all tokens. 153 | for (int tokenPointer = 0; tokenPointer < tokens.size(); ) { 154 | Token token = tokens.get(tokenPointer); 155 | System.out.println(token); 156 | switch (token) { 157 | case NEXT: 158 | // increment the data pointer (to point to the next cell 159 | // to the 160 | // right). 161 | dataPointer = (dataPointer == data.length - 1 ? 0 : dataPointer + 1); 162 | break; 163 | case PREVIOUS: 164 | // decrement the data pointer (to point to the next cell 165 | // to the 166 | // left). 167 | dataPointer = (dataPointer == 0 ? data.length - 1 : dataPointer - 1); 168 | break; 169 | case PLUS: 170 | // increment (increase by one) the byte at the data 171 | // pointer. 172 | data[dataPointer]++; 173 | break; 174 | case MINUS: 175 | // decrement (decrease by one) the byte at the data 176 | // pointer. 177 | data[dataPointer]--; 178 | break; 179 | case OUTPUT: 180 | // Output the byte at the current index in a character. 181 | //outWriter.write((char) data[dataPointer]); 182 | // Flush the outputstream. 183 | //outWriter.flush(); 184 | break; 185 | case INPUT: 186 | // accept one byte of input, storing its value in the 187 | // byte at the data pointer. 188 | data[dataPointer] = (byte) consoleReader.read(); 189 | break; 190 | case BRACKET_LEFT: 191 | if (data[dataPointer] == 0) { 192 | int level = 1; 193 | while (level > 0) { 194 | tokenPointer++; 195 | 196 | if (tokens.get(tokenPointer).equals(Token.BRACKET_LEFT)) 197 | level++; 198 | else if (tokens.get(tokenPointer).equals(Token.BRACKET_RIGHT)) 199 | level--; 200 | } 201 | } 202 | break; 203 | case BRACKET_RIGHT: 204 | if (data[dataPointer] != 0) { 205 | int level = 1; 206 | while (level > 0) { 207 | tokenPointer--; 208 | 209 | if (tokens.get(tokenPointer).equals(Token.BRACKET_LEFT)) 210 | level--; 211 | else if (tokens.get(tokenPointer).equals(Token.BRACKET_RIGHT)) 212 | level++; 213 | } 214 | } 215 | break; 216 | } 217 | 218 | tokenPointer++; 219 | } 220 | // Clear all data. 221 | initate(data.length); 222 | } 223 | 224 | 225 | } 226 | -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/main/java/net/mooctest/TrollScriptEngine.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 Fabian M. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package net.mooctest; 17 | 18 | import java.io.InputStream; 19 | import java.io.OutputStream; 20 | import java.io.PrintStream; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * The {@link TrollScriptEngine} is an implementation for the 26 | * brainfuck derivative TrollScript. 27 | * 28 | * @author Fabian M. 29 | */ 30 | public class TrollScriptEngine extends BrainfuckEngine { 31 | 32 | /** 33 | * The default length of a token. 34 | */ 35 | protected int defaultTokenLength = 3; 36 | /** 37 | * The {@link Token} class contains tokens in TrollScript. 38 | * 39 | * @author Fabian M. 40 | */ 41 | protected static class Token { 42 | 43 | public final static String START = "tro"; 44 | public final static String NEXT = "ooo"; 45 | public final static String PREVIOUS = "ool"; 46 | public final static String PLUS = "olo"; 47 | public final static String MINUS = "oll"; 48 | public final static String OUTPUT = "loo"; 49 | public final static String INPUT = "lol"; 50 | public final static String BRACKET_LEFT = "llo"; 51 | public final static String BRACKET_RIGHT = "lll"; 52 | public final static String END = "ll."; 53 | } 54 | 55 | /** 56 | * Constructs a new {@link TrollScriptEngine} instance. 57 | * 58 | * @param cells 59 | * The amount of memory cells. 60 | */ 61 | public TrollScriptEngine(int cells) { 62 | this(cells, new PrintStream(System.out), System.in); 63 | } 64 | 65 | /** 66 | * Constructs a new {@link TrollScriptEngine} instance. 67 | * 68 | * @param cells 69 | * The amount of memory cells. 70 | * @param out 71 | * The outputstream of this program. 72 | */ 73 | public TrollScriptEngine(int cells, OutputStream out) { 74 | this(cells, out, System.in); 75 | } 76 | 77 | /** 78 | * Constructs a new {@link TrollScriptEngine} instance. 79 | * 80 | * @param cells 81 | * The amount of memory cells. 82 | * @param out 83 | * The printstream of this program. 84 | * @param in 85 | * The outputstream of this program. 86 | */ 87 | public TrollScriptEngine(int cells, OutputStream out, InputStream in) { 88 | super(cells, out, in); 89 | } 90 | 91 | /** 92 | * Interprets the given string. 93 | * 94 | * @param str 95 | * The string to interpret. 96 | * @throws Exception 97 | */ 98 | @Override 99 | public void interpret(String str) throws Exception { 100 | // Is this program already started? 101 | boolean started = false; 102 | // List with tokens.defaultTokenLenght 103 | List tokens = new ArrayList(); 104 | // It fine that all TrollScript tokens are 3 characters long :) 105 | // So we aren't going to loop through all characters. 106 | for (; charPointer < str.length(); ) { 107 | String token = ""; 108 | if (charPointer + defaultTokenLength <= str.length()) 109 | // The string we found. 110 | token = str.substring(charPointer, charPointer + defaultTokenLength); 111 | else 112 | token = str.substring(charPointer, charPointer 113 | + (str.length() - charPointer)); 114 | // Is it a token? 115 | if (isValidToken(token)) { 116 | if (token.equalsIgnoreCase(Token.START)) 117 | started = true; 118 | else if (token.equalsIgnoreCase(Token.END)) 119 | break; 120 | else if (started) 121 | tokens.add(token); 122 | charPointer += defaultTokenLength; 123 | } else if (charPointer + defaultTokenLength > str.length()) { 124 | charPointer += (str.length() - charPointer); 125 | } else { 126 | charPointer++; 127 | } 128 | } 129 | 130 | // Loop through all tokens. 131 | for (int tokenPointer = 0; tokenPointer < tokens.size(); ) { 132 | String token = tokens.get(tokenPointer); 133 | 134 | if (token.equalsIgnoreCase(Token.NEXT)) { 135 | // increment the data pointer (to point to the next cell 136 | // to the 137 | // right). 138 | dataPointer = (dataPointer == data.length - 1 ? 0 : dataPointer + 1); 139 | } 140 | if (token.equalsIgnoreCase(Token.PREVIOUS)) { 141 | // decrement the data pointer (to point to the next cell 142 | // to the 143 | // left). 144 | dataPointer = (dataPointer == 0 ? data.length - 1 : dataPointer - 1); 145 | } 146 | if (token.equalsIgnoreCase(Token.PLUS)) { 147 | // increment (increase by one) the byte at the data 148 | // pointer. 149 | data[dataPointer]++; 150 | } 151 | if (token.equalsIgnoreCase(Token.MINUS)) { 152 | // decrement (decrease by one) the byte at the data 153 | // pointer. 154 | data[dataPointer]--; 155 | } 156 | if (token.equalsIgnoreCase(Token.OUTPUT)) { 157 | // Output the byte at the current index in a character. 158 | outWriter.write((char) data[dataPointer]); 159 | // Flush the outputstream. 160 | outWriter.flush(); 161 | } 162 | if (token.equalsIgnoreCase(Token.INPUT)) { 163 | // accept one byte of input, storing its value in the 164 | // byte at the data pointer. 165 | data[dataPointer] = (byte) consoleReader.read(); 166 | } 167 | if (token.equalsIgnoreCase(Token.BRACKET_LEFT)) { 168 | if (data[dataPointer] == 0) { 169 | int level = 1; 170 | while (level > 0) { 171 | tokenPointer++; 172 | 173 | if (tokens.get(tokenPointer).equalsIgnoreCase(Token.BRACKET_LEFT)) 174 | level++; 175 | else if (tokens.get(tokenPointer).equalsIgnoreCase(Token.BRACKET_RIGHT)) 176 | level--; 177 | } 178 | } 179 | } 180 | if (token.equalsIgnoreCase(Token.BRACKET_RIGHT)) { 181 | if (data[dataPointer] != 0) { 182 | int level = 1; 183 | while (level > 0) { 184 | tokenPointer--; 185 | 186 | if (tokens.get(tokenPointer).equalsIgnoreCase(Token.BRACKET_LEFT)) 187 | level--; 188 | else if (tokens.get(tokenPointer).equalsIgnoreCase(Token.BRACKET_RIGHT)) 189 | level++; 190 | } 191 | } 192 | } 193 | 194 | tokenPointer++; 195 | } 196 | // Clear all data. 197 | initate(data.length); 198 | } 199 | 200 | /** 201 | * Is the given token a valid TrollScript token. 202 | * 203 | * @param token 204 | * The token to check. 205 | * @return true if the given token is a valid 206 | * TrollScript token, false otherwise. 207 | */ 208 | protected boolean isValidToken(String token) { 209 | if (token.equalsIgnoreCase(Token.START) || token.equalsIgnoreCase(Token.NEXT) 210 | || token.equalsIgnoreCase(Token.PREVIOUS) || token.equalsIgnoreCase(Token.PLUS) 211 | || token.equalsIgnoreCase(Token.MINUS) || token.equalsIgnoreCase(Token.OUTPUT) 212 | || token.equalsIgnoreCase(Token.INPUT) 213 | || token.equalsIgnoreCase(Token.BRACKET_LEFT) 214 | || token.equalsIgnoreCase(Token.BRACKET_RIGHT) 215 | || token.equalsIgnoreCase(Token.END)) { 216 | return true; 217 | } 218 | return false; 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/main/resources/net/mooctest/demo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepAQ/SoftwareTesting/9ee0a11c136fc8737e023da19a203381ef5728a3/JUnit/Brainfuck/src/main/resources/net/mooctest/demo.txt -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/test/java/net/mooctest/BrainfuckEngineTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.File; 9 | import java.io.FileOutputStream; 10 | 11 | public class BrainfuckEngineTest { 12 | @Test 13 | public void testConstruct() { 14 | new BrainfuckEngine(10); 15 | new BrainfuckEngine(10, System.out); 16 | new BrainfuckEngine(10, System.out, System.in); 17 | try { 18 | new BrainfuckEngine(-1); 19 | Assert.fail(); 20 | } catch (Exception e) { 21 | } 22 | } 23 | 24 | private void testWithFile(String prog, String input, String expectedOutput) throws Exception { 25 | File file = new File("test"); 26 | FileOutputStream fos = new FileOutputStream(file); 27 | fos.write(prog.getBytes()); 28 | fos.flush(); 29 | fos.close(); 30 | 31 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 32 | ByteArrayInputStream is = new ByteArrayInputStream(input.getBytes()); 33 | BrainfuckEngine engine = new BrainfuckEngine(1024, os, is); 34 | engine.interpret(file); 35 | is.close(); 36 | os.close(); 37 | Assert.assertEquals(expectedOutput, os.toString()); 38 | Assert.assertEquals(1, engine.lineCount); 39 | Assert.assertTrue(engine.columnCount > 0); 40 | } 41 | 42 | @Test 43 | public void testHelloWorld() throws Exception { 44 | testWithFile("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.", "", "Hello World!\n"); 45 | } 46 | 47 | @Test 48 | public void testMultiply() throws Exception { 49 | testWithFile(",>,,>++++++++[<------<------>>-]<<[>[>+>+<<-]>>[<<+>>-]<<<-]>>>++++++[<++++++++>-],<.", "2*3", "6"); 50 | } 51 | 52 | @Test 53 | public void testCellRange() throws Exception { 54 | BrainfuckEngine engine = new BrainfuckEngine(1); 55 | try { 56 | engine.interpret("<"); 57 | Assert.fail(); 58 | } catch (Exception e) { 59 | Assert.assertTrue(e.getMessage().contains("negative")); 60 | } 61 | engine.interpret(">"); 62 | try { 63 | engine.interpret(">>"); 64 | Assert.fail(); 65 | } catch (Exception e) { 66 | Assert.assertTrue(e.getMessage().contains("out of range")); 67 | } 68 | } 69 | 70 | @Test 71 | public void testDataClean() throws Exception { 72 | BrainfuckEngine engine = new BrainfuckEngine(1); 73 | Assert.assertEquals(0, engine.data[0]); 74 | engine.interpret("+++"); 75 | Assert.assertEquals(0, engine.data[0]); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/test/java/net/mooctest/OokEngineTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.*; 7 | 8 | public class OokEngineTest { 9 | @Test 10 | public void testConstruct() { 11 | new OokEngine(10); 12 | new OokEngine(10, System.out); 13 | new OokEngine(10, System.out, System.in); 14 | try { 15 | new OokEngine(-1); 16 | Assert.fail(); 17 | } catch (Exception e) { 18 | } 19 | } 20 | 21 | private void testWithFile(String prog, String input, String expectedDebugOutput) throws Exception { 22 | File file = new File("test"); 23 | FileOutputStream fos = new FileOutputStream(file); 24 | fos.write(prog.getBytes()); 25 | fos.flush(); 26 | fos.close(); 27 | 28 | PrintStream sysOut = System.out; 29 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 30 | ByteArrayInputStream is = new ByteArrayInputStream(input.getBytes()); 31 | System.setOut(new PrintStream(os)); 32 | OokEngine engine = new OokEngine(1024, os, is); 33 | engine.interpret(file); 34 | is.close(); 35 | os.close(); 36 | System.setOut(sysOut); 37 | Assert.assertEquals(expectedDebugOutput, os.toString().replaceAll("\\s", "")); 38 | } 39 | 40 | @Test 41 | public void testHelloWorld() throws Exception { 42 | testWithFile("Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook! Ook! Ook? Ook! Ook? Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook? Ook. Ook. Ook! Ook.", "", "NEXTPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSBRACKET_LEFTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSOUTPUTNEXTPLUSPLUSPLUSPLUSPLUSPLUSPLUSBRACKET_LEFTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSOUTPUTPLUSPLUSPLUSPLUSPLUSPLUSPLUSOUTPUTOUTPUTPLUSPLUSPLUSOUTPUTNEXTNEXTNEXTPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSBRACKET_LEFTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSOUTPUTNEXTNEXTNEXTPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSBRACKET_LEFTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSPLUSNEXTMINUSBRACKET_RIGHTPREVIOUSMINUSMINUSMINUSOUTPUTPREVIOUSPREVIOUSPREVIOUSPREVIOUSOUTPUTPLUSPLUSPLUSOUTPUTMINUSMINUSMINUSMINUSMINUSMINUSOUTPUTMINUSMINUSMINUSMINUSMINUSMINUSMINUSMINUSOUTPUTNEXTNEXTPLUSOUTPUT"); 43 | } 44 | 45 | @Test 46 | public void testInput() throws Exception { 47 | testWithFile("Ook! Ook? Ook! Ook? Ook? Ook! Ook? Ook! Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? Ook! Ook? Ook? Ook! Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook! Ook! Ook.", "?", "BRACKET_LEFTPLUSPLUSBRACKET_LEFTNEXTBRACKET_LEFTPREVIOUSMINUSBRACKET_RIGHTNEXTBRACKET_LEFTPREVIOUSMINUSBRACKET_RIGHTINPUTOUTPUT"); 48 | } 49 | 50 | @Test 51 | public void testInvalidToken() throws Exception { 52 | testWithFile("Ook??? Ook! Ook.", "", "OUTPUT"); 53 | testWithFile("Ook!!!", "", ""); 54 | } 55 | 56 | @Test 57 | public void testCellRange() throws Exception { 58 | PrintStream sysOut = System.out; 59 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 60 | System.setOut(new PrintStream(os)); 61 | 62 | OokEngine engine = new OokEngine(3, os); 63 | engine.interpret("Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook! Ook! Ook? Ook. Ook? Ook. Ook? Ook. Ook? Ook. Ook! Ook! Ook? Ook!"); 64 | 65 | os.close(); 66 | System.setOut(sysOut); 67 | Assert.assertEquals("PLUSPLUSPLUSPLUSPLUSPLUSBRACKET_LEFTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHTNEXTNEXTNEXTMINUSPREVIOUSPREVIOUSPREVIOUSPREVIOUSMINUSBRACKET_RIGHT", os.toString().replaceAll("\\s", "")); 68 | Assert.assertEquals(0, engine.data[0]); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /JUnit/Brainfuck/src/test/java/net/mooctest/TrollScriptEngineTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.io.*; 7 | 8 | public class TrollScriptEngineTest { 9 | @Test 10 | public void testConstruct() { 11 | new TrollScriptEngine(10); 12 | new TrollScriptEngine(10, System.out); 13 | new TrollScriptEngine(10, System.out, System.in); 14 | try { 15 | new TrollScriptEngine(-1); 16 | Assert.fail(); 17 | } catch (Exception e) { 18 | } 19 | } 20 | 21 | private void testWithFile(String prog, String input, String expectedOutput) throws Exception { 22 | File file = new File("test"); 23 | FileOutputStream fos = new FileOutputStream(file); 24 | fos.write(prog.getBytes()); 25 | fos.flush(); 26 | fos.close(); 27 | 28 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 29 | ByteArrayInputStream is = new ByteArrayInputStream(input.getBytes()); 30 | TrollScriptEngine engine = new TrollScriptEngine(1024, os, is); 31 | engine.interpret(file); 32 | is.close(); 33 | os.close(); 34 | Assert.assertEquals(expectedOutput, os.toString()); 35 | } 36 | 37 | @Test 38 | public void testHelloWorld() throws Exception { 39 | testWithFile("Trooloolooloolooloolooloolooloolollooooolooloolooloolooloolooooolooloolooloolooloolooloolooloooooloolooloooooloooloolooloololllllooooloololoooooololooolooloolooloolooloololoolooolooloololooooooloololooooloololooloolooloolooloolooloolooloolooloolooloololooooolooolooloololooollollollollollolllooollollollollollollollollloooooololooooolooll.", "", "Hello World!\n"); 40 | } 41 | 42 | @Test 43 | public void testFib() throws Exception { 44 | testWithFile("Trooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooooolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloooooloolooloolooloolooloolooloolooloolooloolooloolooooooooloooloollloooooooooooooolooloolooloolooloolooloolooloooloollloolloooolooooollllooooolooooooolllooolloololloolloololoooollloooolooooooolllooloolooloolooloollllooollooololooooolllllooolloolllllooooooooooloolooloolooloolooloolooloolooollloolloooollllooooolooooooolllooolloololloolloololoooollloooolooooooollloolooloolooloollllooolloollllloooooollooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloololoolloolllllllloolllooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloololoolloolllllllloolooloololoolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloolooloololoolloollllloolooloolooloolooloolloooooloooooooollooooooooloooloololllllooolloooooloooloololooooolllllooollooololooooollllloolooloololllllooloololoololooloolooll.", "", "1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 121, 98, 219, ..."); 45 | } 46 | 47 | @Test 48 | public void testIO() throws Exception { 49 | testWithFile("Trolollooloolooll.", "?", "???"); 50 | testWithFile("Trolollooloolool.", "?", "???"); 51 | } 52 | 53 | @Test 54 | public void testInvalidToken() throws Exception { 55 | testWithFile("Trol", "", ""); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/Event.java: -------------------------------------------------------------------------------- 1 | 2 | abstract class Event { 3 | 4 | Event() { 5 | 6 | } 7 | 8 | abstract int getValue(); 9 | 10 | abstract Event getLeft(); 11 | 12 | abstract Event getRight(); 13 | 14 | abstract int min(); 15 | 16 | abstract int max(); 17 | 18 | final int maxDepth() { 19 | return maxDepth(0); 20 | } 21 | 22 | protected abstract int maxDepth(int depth); 23 | 24 | abstract boolean isLeaf(); 25 | 26 | abstract Event lift(int m); 27 | 28 | abstract Event sink(int m); 29 | 30 | abstract Event normalize(); 31 | 32 | abstract boolean leq(Event other); 33 | 34 | abstract Event join(Event other); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/Events.java: -------------------------------------------------------------------------------- 1 | 2 | final class Events { 3 | 4 | static Event zero() { 5 | return with(0); 6 | } 7 | 8 | static Event with(int value) { 9 | return new LeafEvent(value); 10 | } 11 | 12 | static Event with(int value, Event left, Event right) { 13 | return new NonLeafEvent(value, left, right); 14 | } 15 | 16 | private Events() { } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/Filler.java: -------------------------------------------------------------------------------- 1 | 2 | final class Filler { 3 | 4 | static Event fill(ID id, Event event) { 5 | if (id.isLeaf()) { 6 | return fillWithLeafID(id, event); 7 | } 8 | else if (event.isLeaf()) { 9 | return event; 10 | } 11 | else { 12 | return fillNonLeafs(id, event); 13 | } 14 | } 15 | 16 | private static Event fillWithLeafID(ID leafID, Event event) { 17 | if (leafID.isZero()) { 18 | return event; 19 | } 20 | else { 21 | return Events.with(event.max()); 22 | } 23 | } 24 | 25 | private static Event fillNonLeafs(ID id, Event event) { 26 | if (id.getLeft().isOne()) { 27 | return fillLeftOneID(id, event); 28 | } 29 | else if (id.getRight().isOne()) { 30 | return fillRightOneID(id, event); 31 | } 32 | else { 33 | return fillLeftRight(id, event); 34 | } 35 | } 36 | 37 | private static Event fillLeftOneID(ID id, Event event) { 38 | Event filledRight = fillRight(id, event); 39 | int max = Math.max(event.getLeft().max(), filledRight.min()); 40 | return Events.with(event.getValue(), Events.with(max), filledRight).normalize(); 41 | } 42 | 43 | private static Event fillRight(ID id, Event event) { 44 | return fill(id.getRight(), event.getRight()); 45 | } 46 | 47 | private static Event fillRightOneID(ID id, Event event) { 48 | Event filledLeft = fillLeft(id, event); 49 | int max = Math.max(event.getRight().max(), filledLeft.min()); 50 | return Events.with(event.getValue(), filledLeft, Events.with(max)).normalize(); 51 | } 52 | 53 | private static Event fillLeft(ID id, Event event) { 54 | return fill(id.getLeft(), event.getLeft()); 55 | } 56 | 57 | private static Event fillLeftRight(ID id, Event event) { 58 | return Events.with(event.getValue(), fillLeft(id, event), fillRight(id, event)) 59 | .normalize(); 60 | } 61 | 62 | private Filler() { } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/GrowResult.java: -------------------------------------------------------------------------------- 1 | 2 | final class GrowResult { 3 | 4 | private final Event event; 5 | private int cost; 6 | 7 | GrowResult(Event event, int cost) { 8 | this.event = event; 9 | this.cost = cost; 10 | } 11 | 12 | Event getEvent() { 13 | return event; 14 | } 15 | 16 | int getCost() { 17 | return cost; 18 | } 19 | 20 | void setCost(int cost) { 21 | this.cost = cost; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/Grower.java: -------------------------------------------------------------------------------- 1 | 2 | final class Grower { 3 | 4 | static Event grow(ID id, Event event) { 5 | return innerGrow(id, event).getEvent(); 6 | } 7 | 8 | private static GrowResult innerGrow(ID id, Event event) { 9 | if (id.isLeaf()) { 10 | return growLeafID(id, event); 11 | } 12 | else { 13 | return growNonLeafID(id, event); 14 | } 15 | } 16 | 17 | private static GrowResult growLeafID(ID id, Event event) { 18 | if (id.isOne() && event.isLeaf()) { 19 | return new GrowResult(Events.with(event.getValue() + 1), 0); 20 | } 21 | else { 22 | throw new IllegalArgumentException("Illegal arguments: " + id + " and " + event); 23 | } 24 | } 25 | 26 | private static GrowResult growNonLeafID(ID id, Event event) { 27 | if (event.isLeaf()) { 28 | return growLeafEvent(id, event); 29 | } 30 | else if (id.getLeft().isZero()) { 31 | return growOnRight(id, event); 32 | } 33 | else if (id.getRight().isZero()) { 34 | return growOnLeft(id, event); 35 | } 36 | else { 37 | return growOnBothSides(id, event); 38 | } 39 | } 40 | 41 | private static GrowResult growLeafEvent(ID id, Event event) { 42 | GrowResult er = innerGrow(id, Events.with(event.getValue(), Events.zero(), Events.zero())); 43 | er.setCost(er.getCost() + event.maxDepth() + 1); 44 | return er; 45 | } 46 | 47 | private static GrowResult growOnRight(ID id, Event event) { 48 | GrowResult rightGrowth = growRight(id, event); 49 | return rightGrowth(event, rightGrowth); 50 | } 51 | 52 | private static GrowResult growRight(ID id, Event event) { 53 | return innerGrow(id.getRight(), event.getRight()); 54 | } 55 | 56 | private static GrowResult rightGrowth(Event event, GrowResult growth) { 57 | Event result = Events.with(event.getValue(), 58 | event.getLeft(), growth.getEvent()); 59 | return new GrowResult(result, growth.getCost() + 1); 60 | } 61 | 62 | private static GrowResult growOnLeft(ID id, Event event) { 63 | GrowResult leftGrowth = growLeft(id, event); 64 | return leftGrowth(event, leftGrowth); 65 | } 66 | 67 | private static GrowResult growLeft(ID id, Event event) { 68 | return innerGrow(id.getLeft(), event.getLeft()); 69 | } 70 | 71 | private static GrowResult leftGrowth(Event event, GrowResult growth) { 72 | Event result = Events.with(event.getValue(), 73 | growth.getEvent(), event.getRight()); 74 | return new GrowResult(result, growth.getCost() + 1); 75 | } 76 | 77 | private static GrowResult growOnBothSides(ID id, Event event) { 78 | GrowResult leftGrowth = growLeft(id, event); 79 | GrowResult rightGrowth = growRight(id, event); 80 | if (leftGrowth.getCost() < rightGrowth.getCost()) { 81 | return leftGrowth(event, leftGrowth); 82 | } 83 | else { 84 | return rightGrowth(event, rightGrowth); 85 | } 86 | } 87 | 88 | private Grower() { } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/ID.java: -------------------------------------------------------------------------------- 1 | 2 | abstract class ID { 3 | 4 | abstract ID getLeft(); 5 | 6 | abstract ID getRight(); 7 | 8 | abstract boolean isLeaf(); 9 | 10 | abstract boolean isZero(); 11 | 12 | abstract boolean isOne(); 13 | 14 | abstract ID normalize(); 15 | 16 | abstract ID[] split(); 17 | 18 | abstract ID sum(ID other); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/IDs.java: -------------------------------------------------------------------------------- 1 | 2 | final class IDs { 3 | 4 | static ID zero() { 5 | return new LeafID(0); 6 | } 7 | 8 | static ID one() { 9 | return new LeafID(1); 10 | } 11 | 12 | static ID with(ID id1, ID id2) { 13 | return new NonLeafID(id1, id2); 14 | } 15 | 16 | private IDs() { } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/ITClocks.java: -------------------------------------------------------------------------------- 1 | 2 | public class ITClocks { 3 | private static final int lift(Event e) { 4 | return e.isLeaf() ? 0 : e.getValue(); 5 | } 6 | 7 | private static final Event tryLeft(Event e) { 8 | return e.isLeaf() ? e: e.getLeft(); 9 | } 10 | 11 | private static final Event tryRight(Event e) { 12 | return e.isLeaf() ? e : e.getRight(); 13 | } 14 | 15 | /** 16 | * Less than-equal operator for causality: either e1 happens before e2 or e1 17 | * equals e2. 18 | * 19 | * @param offset1 20 | * The accumulated lifted value for event e1. 21 | * @param e1 22 | * The first event being compared. 23 | * @param offset2 24 | * The accumulated lifted value for event e2 25 | * @param e2 26 | * The second event being compared. 27 | * @return Returns if e1 is precedes or equals e2. 28 | */ 29 | private static final boolean lessThanEquals(final int offset1, 30 | final Event e1, final int offset2, Event e2) { 31 | final int new_a = offset1 + e1.getValue(); 32 | if (e1.isLeaf()) { 33 | return new_a <= offset2 + e2.getValue(); 34 | } 35 | final int new_b = lift(e2) + offset2; 36 | if (!lessThanEquals(new_a, e1.getLeft(), new_b, tryLeft(e2))) { 37 | return false; 38 | } 39 | return lessThanEquals(new_a, e1.getRight(), new_b, tryRight(e2)); 40 | } 41 | 42 | /** 43 | * The causality between two events. 44 | * 45 | */ 46 | private static enum Order { 47 | HAPPENS_BEFORE, HAPPENS_AFTER, EQUALS, UNCOMPARABLE; 48 | public boolean isUnordered() { 49 | return this == EQUALS || this == UNCOMPARABLE; 50 | } 51 | 52 | /** 53 | * Compose two causality events. 54 | * 55 | * @param c1 56 | * @param c2 57 | * @return 58 | */ 59 | public static Order compose(Order c1, Order c2) { 60 | switch (c1) { 61 | case EQUALS: 62 | return c2; 63 | case UNCOMPARABLE: 64 | return Order.UNCOMPARABLE; 65 | case HAPPENS_BEFORE: { 66 | switch (c2) { 67 | case HAPPENS_BEFORE: 68 | case EQUALS: 69 | return Order.HAPPENS_BEFORE; 70 | default: 71 | return Order.UNCOMPARABLE; 72 | } 73 | } 74 | case HAPPENS_AFTER: { 75 | switch (c2) { 76 | case HAPPENS_AFTER: 77 | case EQUALS: 78 | return Order.HAPPENS_AFTER; 79 | default: 80 | return Order.UNCOMPARABLE; 81 | } 82 | } 83 | } 84 | throw new IllegalStateException(); 85 | } 86 | } 87 | 88 | /** 89 | * Base case of comparison. 90 | * 91 | * @param offset 92 | * @param e1 93 | * @param e2 94 | * @return 95 | */ 96 | private static Order compare0(int offset, Event e1, Event e2) { 97 | if (e1.getValue() < e2.getValue()) { 98 | return lessThanEquals(offset, e1, offset, e2) ? Order.HAPPENS_BEFORE 99 | : Order.UNCOMPARABLE; 100 | } else if (e1.getValue() > e2.getValue()) { 101 | return lessThanEquals(offset, e2, offset, e1) ? Order.HAPPENS_AFTER 102 | : Order.UNCOMPARABLE; 103 | } 104 | // Since one of the events is a leaf event, then only one leq is called. 105 | if (lessThanEquals(offset, e1, offset, e2)) { 106 | if (lessThanEquals(offset, e2, offset, e1)) { 107 | return Order.EQUALS; 108 | } 109 | return Order.HAPPENS_BEFORE; 110 | } 111 | if (lessThanEquals(offset, e2, offset, e1)) { 112 | return Order.HAPPENS_AFTER; 113 | } 114 | return Order.UNCOMPARABLE; 115 | } 116 | 117 | /** 118 | * Checks if a given event happens-before (LT), happens-after (GT), equals, 119 | * or is undefined 120 | * 121 | * @param offset 122 | * @param e1 123 | * @param e2 124 | * @return 125 | */ 126 | private static Order compare(int offset, Event e1, Event e2) { 127 | if (e1.getValue() != e2.getValue() || e1.isLeaf() || e2.isLeaf()) { 128 | return compare0(offset, e1, e2); 129 | } 130 | int newOffset = offset + e1.getValue(); 131 | return Order.compose(compare(newOffset, e1.getLeft(), e2.getLeft()), 132 | compare(newOffset, e1.getRight(), e2.getRight())); 133 | } 134 | 135 | /** 136 | * Check if timestamp s1 happens before or equals to timestamp s2 137 | * 138 | * @param e2 139 | * @return 140 | */ 141 | public static boolean lessThanEquals(Stamp s1, Stamp s2) { 142 | return lessThanEquals(s1.getEvent(), s2.getEvent()); 143 | } 144 | 145 | /** 146 | * Check if event e1 precedes or equals event e2 147 | * 148 | * @param e2 149 | * @return 150 | */ 151 | public static boolean lessThanEquals(Event e1, Event e2) { 152 | return lessThanEquals(0, e1, 0, e2); 153 | } 154 | 155 | /** 156 | * Checks if this event is concurrent with e. If 157 | * e1.isConcurrent(e2), then e2.isConcurrent(e1). 158 | * 159 | * @param other 160 | * The event this object is being compared against. 161 | * @return 162 | */ 163 | public static boolean isConcurrent(Event e1, Event e2) { 164 | return compare(0, e1, e2).isUnordered(); 165 | } 166 | 167 | /** 168 | * Checks if this event happened before the other. If neither event happened 169 | * before the other, we say that they are concurrent. 170 | * 171 | * @param e 172 | * @return 173 | */ 174 | public static boolean happensBefore(Stamp s1, Stamp s2) { 175 | return happensBefore(s1.getEvent(), s2.getEvent()); 176 | } 177 | /** 178 | * Checks if this event happened before the other. If neither event happened 179 | * before the other, we say that they are concurrent. 180 | * 181 | * @param e 182 | * @return 183 | */ 184 | public static boolean happensBefore(Event e1, Event e2) { 185 | return compare(0, e1, e2) == Order.HAPPENS_BEFORE; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/LeafEvent.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.Serializable; 3 | 4 | final class LeafEvent extends Event implements Serializable { 5 | 6 | private static final long serialVersionUID = -7441138365249091187L; 7 | 8 | private final int value; 9 | 10 | LeafEvent() { 11 | value = 0; 12 | } 13 | 14 | LeafEvent(int value) { 15 | this.value = value; 16 | } 17 | 18 | @Override 19 | int getValue() { 20 | return value; 21 | } 22 | 23 | @Override 24 | Event getLeft() { 25 | return null; 26 | } 27 | 28 | @Override 29 | Event getRight() { 30 | return null; 31 | } 32 | 33 | @Override 34 | int max() { 35 | return value; 36 | } 37 | 38 | @Override 39 | int min() { 40 | return value; 41 | } 42 | 43 | @Override 44 | protected int maxDepth(int depth) { 45 | return depth; 46 | } 47 | 48 | @Override 49 | boolean isLeaf() { 50 | return true; 51 | } 52 | 53 | @Override 54 | Event lift(int m) { 55 | return new LeafEvent(value + m); 56 | } 57 | 58 | @Override 59 | Event sink(int m) { 60 | return new LeafEvent(value - m); 61 | } 62 | 63 | @Override 64 | Event normalize() { 65 | return this; 66 | } 67 | 68 | @Override 69 | boolean leq(Event other) { 70 | return value <= other.getValue(); 71 | } 72 | 73 | @Override 74 | Event join(Event other) { 75 | if (other.isLeaf()) { 76 | return new LeafEvent(Math.max(value, other.getValue())); 77 | } 78 | else { 79 | return Events.with(value, Events.zero(), Events.zero()).join(other); 80 | } 81 | } 82 | 83 | @Override 84 | public boolean equals(Object object) { 85 | if(!(object instanceof LeafEvent)) { 86 | return false; 87 | } 88 | else { 89 | final LeafEvent other = (LeafEvent)object; 90 | return this.value == other.value; 91 | } 92 | } 93 | 94 | @Override 95 | public int hashCode() { 96 | int hash = 5; 97 | hash = 41 * hash + this.value; 98 | return hash; 99 | } 100 | 101 | @Override 102 | public String toString() { 103 | return String.valueOf(value); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/LeafID.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.Serializable; 3 | 4 | final class LeafID extends ID implements Serializable { 5 | 6 | private static final long serialVersionUID = 870626177742300327L; 7 | 8 | private final int value; 9 | 10 | LeafID(int value) { 11 | this.value = value; 12 | } 13 | 14 | int getValue() { 15 | return this.value; 16 | } 17 | 18 | @Override 19 | ID getLeft() { 20 | return null; 21 | } 22 | 23 | @Override 24 | ID getRight() { 25 | return null; 26 | } 27 | 28 | @Override 29 | boolean isZero() { 30 | return value == 0; 31 | } 32 | 33 | @Override 34 | boolean isOne() { 35 | return value == 1; 36 | } 37 | 38 | @Override 39 | boolean isLeaf() { 40 | return true; 41 | } 42 | 43 | @Override 44 | ID normalize() { 45 | return this; 46 | } 47 | 48 | @Override 49 | ID[] split() { 50 | if (isZero()) { 51 | return new ID[] { IDs.zero(), IDs.zero()}; 52 | } 53 | else { // if (isOne()) { 54 | return new ID[] { 55 | IDs.with(IDs.one(), IDs.zero()), 56 | IDs.with(IDs.zero(), IDs.one()) 57 | }; 58 | } 59 | } 60 | 61 | @Override 62 | ID sum(ID other) { 63 | assert other != null; 64 | if (this.isZero()) { 65 | return other; 66 | } 67 | else if (other.isZero()) { 68 | return this; 69 | } 70 | else { 71 | throw new IllegalArgumentException("Can't sum " + this + " with " + other); 72 | } 73 | } 74 | 75 | @Override 76 | public boolean equals(Object object) { 77 | if(!(object instanceof LeafID)) { 78 | return false; 79 | } 80 | else { 81 | LeafID other = (LeafID)object; 82 | return value == other.value; 83 | } 84 | } 85 | 86 | @Override 87 | public int hashCode() { 88 | int hash = 3; 89 | hash = 17 * hash + this.value; 90 | return hash; 91 | } 92 | 93 | @Override 94 | public String toString() { 95 | return String.valueOf(value); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/NonLeafEvent.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.Serializable; 3 | import java.util.Objects; 4 | 5 | final class NonLeafEvent extends Event implements Serializable { 6 | 7 | private static final long serialVersionUID = 4390279981057181340L; 8 | 9 | private final int value; 10 | private final Event left; 11 | private final Event right; 12 | 13 | NonLeafEvent(int value, Event left, Event right) { 14 | this.value = value; 15 | this.left = left; 16 | this.right = right; 17 | } 18 | 19 | @Override 20 | int getValue() { 21 | return value; 22 | } 23 | 24 | Event getLeft() { 25 | return left; 26 | } 27 | 28 | Event getRight() { 29 | return right; 30 | } 31 | 32 | @Override 33 | int min() { 34 | int min = Math.min(left.min(), right.min()); 35 | return value + min; 36 | } 37 | 38 | @Override 39 | int max() { 40 | int max = Math.max(left.max(), right.max()); 41 | return value + max; 42 | } 43 | 44 | @Override 45 | protected int maxDepth(int depth) { 46 | int leftDepth = left.maxDepth(depth + 1); 47 | int rightDepth = right.maxDepth(depth + 1); 48 | return Math.max(leftDepth, rightDepth); 49 | } 50 | 51 | @Override 52 | boolean isLeaf() { 53 | return false; 54 | } 55 | 56 | @Override 57 | Event lift(int m) { 58 | return Events.with(value + m, left, right); 59 | } 60 | 61 | @Override 62 | Event sink(int m) { 63 | return Events.with(value - m, left, right); 64 | } 65 | 66 | @Override 67 | Event normalize() { 68 | if (left.isLeaf() && right.isLeaf() && left.getValue() == right.getValue()) { 69 | return Events.with(value + left.getValue()); 70 | } 71 | else { 72 | int min = Math.min(left.min(), right.min()); 73 | return Events.with(value + min, left.sink(min), right.sink(min)); 74 | } 75 | } 76 | 77 | @Override 78 | boolean leq(Event other) { 79 | if (other.isLeaf()) { 80 | return leqLeaf(other); 81 | } 82 | else { 83 | return leqNonLeafs(other); 84 | } 85 | } 86 | 87 | private boolean leqLeaf(Event other) { 88 | return value <= other.getValue() && 89 | liftedLeft(this).leq(other) && 90 | liftedRight(this).leq(other); 91 | } 92 | 93 | private static Event liftedLeft(Event event) { 94 | return event.getLeft().lift(event.getValue()); 95 | } 96 | 97 | private static Event liftedRight(Event event) { 98 | return event.getRight().lift(event.getValue()); 99 | } 100 | 101 | private boolean leqNonLeafs(Event other) { 102 | return value <= other.getValue() && 103 | liftedLeft(this).leq(liftedLeft(other)) && 104 | liftedRight(this).leq(liftedRight(other)); 105 | } 106 | 107 | @Override 108 | Event join(Event other) { 109 | if (other.isLeaf()) { 110 | return join(Events.with(other.getValue(), Events.zero(), Events.zero())); 111 | } 112 | else { 113 | return joinNonLeaf(other); 114 | } 115 | } 116 | 117 | private Event joinNonLeaf(Event other) { 118 | if (value > other.getValue()) { 119 | return other.join(this); 120 | } 121 | else { 122 | Event join = Events.with(value, leftJoin(other), rightJoin(other)); 123 | return join.normalize(); 124 | } 125 | } 126 | 127 | private Event leftJoin(Event other) { 128 | Event otherLiftedLeft = other.getLeft().lift(other.getValue() - value); 129 | return left.join(otherLiftedLeft); 130 | } 131 | 132 | private Event rightJoin(Event other) { 133 | Event otherLiftedRight = other.getRight().lift(other.getValue() - value); 134 | return right.join(otherLiftedRight); 135 | } 136 | 137 | @Override 138 | public boolean equals(Object object) { 139 | if (!(object instanceof NonLeafEvent)) { 140 | return false; 141 | } 142 | else { 143 | NonLeafEvent other = (NonLeafEvent)object; 144 | return value == other.value && 145 | Objects.equals(left, other.left) && 146 | Objects.equals(right, other.right); 147 | } 148 | } 149 | 150 | @Override 151 | public int hashCode() { 152 | int hash = 7; 153 | hash = 37 * hash + value; 154 | hash = 37 * hash + left.hashCode(); 155 | hash = 37 * hash + right.hashCode(); 156 | return hash; 157 | } 158 | 159 | @Override 160 | public String toString() { 161 | return "(" + value + ", " + left + ", " + right + ")"; 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/NonLeafID.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.Serializable; 3 | import java.util.Objects; 4 | 5 | final class NonLeafID extends ID implements Serializable { 6 | 7 | private static final long serialVersionUID = -5030081211956985797L; 8 | 9 | private final ID left; 10 | private final ID right; 11 | 12 | NonLeafID(ID left, ID right) { 13 | this.left = left; 14 | this.right = right; 15 | } 16 | 17 | ID getLeft() { 18 | return left; 19 | } 20 | 21 | ID getRight() { 22 | return right; 23 | } 24 | 25 | @Override 26 | boolean isOne() { 27 | return false; 28 | } 29 | 30 | @Override 31 | boolean isZero() { 32 | return false; 33 | } 34 | 35 | @Override 36 | boolean isLeaf() { 37 | return false; 38 | } 39 | 40 | @Override 41 | ID normalize() { 42 | return normalize(left.normalize(), right.normalize()); 43 | } 44 | 45 | private static ID normalize(ID left, ID right) { 46 | if (left.isZero() && right.isZero()) { 47 | return IDs.zero(); 48 | } 49 | else if (left.isOne() && right.isOne()) { 50 | return IDs.one(); 51 | } 52 | else { 53 | return IDs.with(left, right); 54 | } 55 | } 56 | 57 | @Override 58 | ID[] split() { 59 | if (left.isZero()) { 60 | return splitWithLeftZero(); 61 | } 62 | else if (right.isZero()) { 63 | return splitWithRightZero(); 64 | } 65 | else { 66 | return new ID[] { 67 | IDs.with(left, IDs.zero()), 68 | IDs.with(IDs.zero(), right) 69 | }; 70 | } 71 | } 72 | 73 | private ID[] splitWithLeftZero() { 74 | ID[] rightSplit = right.split(); 75 | return new ID[] { 76 | IDs.with(IDs.zero(), rightSplit[0]), 77 | IDs.with(IDs.zero(), rightSplit[1]) 78 | }; 79 | } 80 | 81 | private ID[] splitWithRightZero() { 82 | ID[] leftSplit = left.split(); 83 | return new ID[] { 84 | IDs.with(leftSplit[0], IDs.zero()), 85 | IDs.with(leftSplit[1], IDs.zero()) 86 | }; 87 | } 88 | 89 | @Override 90 | ID sum(ID other) { 91 | assert other != null; 92 | if (other.isZero()) { 93 | return this; 94 | } 95 | else if (!other.isLeaf()) { 96 | return sumNonLeaf((NonLeafID)other); 97 | } 98 | else { 99 | throw new IllegalArgumentException("Can't sum " + this + " with 1."); 100 | } 101 | } 102 | 103 | private ID sumNonLeaf(ID other) { 104 | ID leftSum = left.sum(other.getLeft()); 105 | ID rightSum = right.sum(other.getRight()); 106 | ID sum = IDs.with(leftSum, rightSum); 107 | return sum.normalize(); 108 | } 109 | 110 | @Override 111 | public boolean equals(Object object) { 112 | if (!(object instanceof NonLeafID)) { 113 | return false; 114 | } 115 | else { 116 | NonLeafID other = (NonLeafID)object; 117 | return left.equals(other.getLeft()) && 118 | right.equals(other.getRight()); 119 | } 120 | } 121 | 122 | @Override 123 | public int hashCode() { 124 | return Objects.hash(left, right); 125 | } 126 | 127 | @Override 128 | public String toString() { 129 | return "(" + left + ", " + right + ")"; 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /JUnit/ITClocks/src/Stamp.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.Serializable; 3 | 4 | public final class Stamp implements Serializable { 5 | 6 | private static final long serialVersionUID = 1750149585711104601L; 7 | 8 | private final ID id; 9 | private final Event event; 10 | 11 | public Stamp() { 12 | id = IDs.one(); 13 | event = Events.zero(); 14 | } 15 | 16 | Stamp(ID id, Event event) { 17 | this.id = id; 18 | this.event = event; 19 | } 20 | 21 | ID getId() { 22 | return id; 23 | } 24 | 25 | Event getEvent() { 26 | return event; 27 | } 28 | 29 | public Stamp[] fork() { 30 | ID[] ids = id.split(); 31 | return new Stamp[] { 32 | new Stamp(ids[0], event), 33 | new Stamp(ids[1], event) 34 | }; 35 | } 36 | 37 | public Stamp[] peek() { 38 | return new Stamp[] { 39 | new Stamp(id, event), 40 | new Stamp(IDs.zero(), event) 41 | }; 42 | } 43 | 44 | public Stamp join(Stamp other) { 45 | ID idSum = id.sum(other.id); 46 | Event eventJoin = event.join(other.event); 47 | return new Stamp(idSum, eventJoin); 48 | } 49 | 50 | public Stamp event() { 51 | Event filled = Filler.fill(id, event); 52 | if (!filled.equals(event)) { 53 | return new Stamp(id, filled); 54 | } 55 | else { 56 | return new Stamp(id, Grower.grow(id, event)); 57 | } 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "(" + id + ", " + event + ")"; 63 | } 64 | 65 | @Override 66 | public boolean equals(Object o) { 67 | if (!(o instanceof Stamp)) { 68 | return false; 69 | } 70 | else { 71 | Stamp other = (Stamp) o; 72 | return id.equals(other.getId()) && event.equals(other.getEvent()); 73 | } 74 | } 75 | 76 | @Override 77 | public int hashCode() { 78 | int result = id.hashCode(); 79 | result = 31 * result + event.hashCode(); 80 | return result; 81 | } 82 | 83 | //----------------------------------------- API methods -------------------------------------- 84 | 85 | public Stamp[] send() { 86 | return event().peek(); 87 | } 88 | 89 | public Stamp receive(Stamp other) { 90 | return join(other).event(); 91 | } 92 | 93 | public Stamp[] sync(Stamp other) { 94 | return join(other).fork(); 95 | } 96 | 97 | public boolean leq(Stamp other) { 98 | return event.leq(other.event); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/FillerTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.After; 2 | import org.junit.Before; 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.fail; 6 | 7 | public class FillerTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void test() { 19 | ID nl00 = IDs.with(IDs.zero(), IDs.zero()); 20 | ID nl01 = IDs.with(IDs.zero(), IDs.one()); 21 | ID nl10 = IDs.with(IDs.one(), IDs.zero()); 22 | ID nl11 = IDs.with(IDs.one(), IDs.one()); 23 | ID nl101 = IDs.with(IDs.one(), IDs.with(IDs.zero(), IDs.one())); 24 | Event e0 = Events.zero(); 25 | Event e1 = Events.with(0, e0, e0); 26 | Filler.fill(nl00, e0); 27 | Filler.fill(nl01, e0); 28 | Filler.fill(nl10, e0); 29 | Filler.fill(nl11, e0); 30 | Filler.fill(nl101, e0); 31 | Filler.fill(nl00, e1); 32 | Filler.fill(nl01, e1); 33 | Filler.fill(nl10, e1); 34 | Filler.fill(nl11, e1); 35 | Filler.fill(nl101, e1); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/GrowerTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class GrowerTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void test() { 19 | ID nl00 = IDs.with(IDs.zero(), IDs.zero()); 20 | ID nl01 = IDs.with(IDs.zero(), IDs.one()); 21 | ID nl10 = IDs.with(IDs.one(), IDs.zero()); 22 | ID nl11 = IDs.with(IDs.one(), IDs.one()); 23 | ID nl101 = IDs.with(IDs.one(), IDs.with(IDs.zero(), IDs.one())); 24 | Event e0 = Events.zero(); 25 | try { 26 | Grower.grow(nl00, e0); 27 | fail(); 28 | } catch (Exception e) { 29 | } 30 | Grower.grow(nl01, e0); 31 | Grower.grow(nl10, e0); 32 | Grower.grow(nl11, e0); 33 | Grower.grow(nl101, e0); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/IDsTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class IDsTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void testWithIDs() { 19 | assertEquals(new NonLeafID(IDs.zero(), IDs.zero()), IDs.with(IDs.zero(), IDs.zero())); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/ITClocksTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.After; 2 | import org.junit.Before; 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class ITClocksTest { 8 | 9 | private ITClocks itc; 10 | 11 | @Before 12 | public void setUp() throws Exception { 13 | itc = new ITClocks(); 14 | } 15 | 16 | @After 17 | public void tearDown() throws Exception { 18 | } 19 | 20 | @Test 21 | public void testLteEvent() { 22 | Event e1 = Events.zero(); 23 | Event e2 = Events.with(1); 24 | Event e3 = Events.with(0, e1, e1); 25 | Event e4 = Events.with(0, e2, e2); 26 | assertTrue(ITClocks.lessThanEquals(e1, e1)); 27 | assertFalse(ITClocks.lessThanEquals(e2, e1)); 28 | assertTrue(ITClocks.lessThanEquals(e1, e3)); 29 | assertFalse(ITClocks.lessThanEquals(e2, e3)); 30 | assertTrue(ITClocks.lessThanEquals(e3, e1)); 31 | assertFalse(ITClocks.lessThanEquals(e4, e1)); 32 | assertTrue(ITClocks.lessThanEquals(e3, e4)); 33 | assertFalse(ITClocks.lessThanEquals(e4, e3)); 34 | } 35 | 36 | @Test 37 | public void testLteStamp() { 38 | Stamp s1 = new Stamp(); 39 | Stamp s2 = new Stamp(IDs.zero(), Events.zero()); 40 | assertTrue(ITClocks.lessThanEquals(s1, s2)); 41 | assertTrue(ITClocks.lessThanEquals(s1, s1)); 42 | } 43 | 44 | @Test 45 | public void testCmpEvent() { 46 | Event e1 = Events.zero(); 47 | Event e2 = Events.with(2); 48 | Event e3 = Events.with(3, e2, e2); 49 | Event e4 = Events.with(1, e2, e2); 50 | assertTrue(ITClocks.isConcurrent(e1, e1)); // LL 51 | assertFalse(ITClocks.isConcurrent(e1, e2)); // LL False 52 | assertTrue(ITClocks.isConcurrent(e2, e4)); // LN 53 | assertFalse(ITClocks.isConcurrent(e1, e3)); // LN False 54 | assertTrue(ITClocks.isConcurrent(e4, e2)); // NL 55 | assertFalse(ITClocks.isConcurrent(e3, e1)); // NL False 56 | assertTrue(ITClocks.isConcurrent(e4, e4)); // NN 57 | assertFalse(ITClocks.isConcurrent(e3, e4)); // NN False 58 | } 59 | 60 | @Test 61 | public void testUncmp() { 62 | Event e1 = Events.with(1); 63 | Event e2 = Events.with(2); 64 | Event e3 = Events.with(0, e1, e1); 65 | Event e4 = Events.with(0, e2, e2); 66 | Event e5 = Events.with(0, e4, e4); 67 | assertTrue(ITClocks.isConcurrent(e5, e3)); 68 | } 69 | 70 | @Test 71 | public void testHB() { 72 | Event e1 = Events.with(1); 73 | Event e2 = Events.with(2); 74 | Event e3 = Events.with(0, e1, e1); 75 | Event e4 = Events.with(0, e2, e2); 76 | Event e5 = Events.with(0, e1, e2); 77 | Event e6 = Events.with(0, e2, e1); 78 | assertFalse(ITClocks.isConcurrent(e3, e4)); 79 | assertTrue(ITClocks.isConcurrent(e5, e6)); 80 | } 81 | 82 | @Test 83 | public void testHA() { 84 | Event e1 = Events.with(1); 85 | Event e2 = Events.with(2); 86 | Event e3 = Events.with(0, e1, e1); 87 | Event e4 = Events.with(0, e2, e2); 88 | Event e5 = Events.with(0, e1, e2); 89 | Event e6 = Events.with(0, e2, e1); 90 | assertFalse(ITClocks.isConcurrent(e4, e3)); 91 | assertTrue(ITClocks.isConcurrent(e6, e5)); 92 | } 93 | 94 | @Test 95 | public void testCmp0() { 96 | Event e1 = Events.with(1); 97 | Event e2 = Events.with(2); 98 | Event e3 = Events.with(1, e2, e2); 99 | assertFalse(ITClocks.isConcurrent(e1, e3)); 100 | assertFalse(ITClocks.isConcurrent(e3, e1)); 101 | } 102 | 103 | @Test 104 | public void testCmpNull() { 105 | Event e0 = Events.zero(); 106 | try { 107 | ITClocks.isConcurrent(null, null); 108 | fail(); 109 | } catch (Exception e) { 110 | } 111 | try { 112 | ITClocks.isConcurrent(e0, null); 113 | fail(); 114 | } catch (Exception e) { 115 | } 116 | } 117 | 118 | @Test 119 | public void testCmpBefore() { 120 | Event e1 = Events.zero(); 121 | Event e2 = Events.with(1); 122 | Event e3 = Events.with(3, e2, e2); 123 | Event e4 = Events.with(2, e2, e2); 124 | assertFalse(ITClocks.happensBefore(e1, e1)); 125 | assertTrue(ITClocks.happensBefore(e1, e2)); 126 | } 127 | 128 | @Test 129 | public void testCmpBeforeStamp() { 130 | Stamp s1 = new Stamp(); 131 | assertFalse(ITClocks.happensBefore(s1, s1)); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/LeafEventTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class LeafEventTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void test() { 19 | LeafEvent lev = new LeafEvent(); 20 | assertNull(lev.getLeft()); 21 | assertNull(lev.getRight()); 22 | assertEquals(0, lev.max()); 23 | assertEquals(0, lev.min()); 24 | assertEquals(741, lev.lift(741).getValue()); 25 | assertEquals(-741, lev.sink(741).getValue()); 26 | assertEquals(lev, lev.normalize()); 27 | lev.join(Events.with(0, lev, lev)); 28 | assertFalse(lev.equals(null)); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/LeafIDTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class LeafIDTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void test() { 19 | LeafID lid = new LeafID(0); 20 | assertEquals(0, lid.getValue()); 21 | assertNull(lid.getLeft()); 22 | assertNull(lid.getRight()); 23 | assertEquals(lid, lid.normalize()); 24 | assertEquals(IDs.zero(), lid.split()[0]); 25 | assertEquals(IDs.zero(), lid.split()[1]); 26 | assertEquals(IDs.one(), lid.sum(IDs.one())); 27 | assertFalse(lid.equals(null)); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/NonLeafEventTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class NonLeafEventTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void test() { 19 | NonLeafEvent ev = new NonLeafEvent(1, Events.zero(), Events.zero()); 20 | assertEquals(1, ev.min()); 21 | assertEquals(1, ev.max()); 22 | assertEquals(1, ev.maxDepth()); 23 | assertEquals(742, ev.lift(741).getValue()); 24 | assertEquals(-740, ev.sink(741).getValue()); 25 | new NonLeafEvent(0, ev, Events.zero()).normalize(); 26 | assertTrue(ev.leq(ev)); 27 | assertFalse(ev.leq(new NonLeafEvent(0, ev, Events.zero()))); 28 | ev.join(ev); 29 | ev.join(new NonLeafEvent(0, ev, Events.zero())); 30 | assertFalse(ev.equals(null)); 31 | assertTrue(ev.equals(ev)); 32 | ev.hashCode(); 33 | ev.toString(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/NonLeafIDTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.After; 2 | import org.junit.Before; 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertFalse; 6 | import static org.junit.Assert.fail; 7 | 8 | public class NonLeafIDTest { 9 | 10 | @Before 11 | public void setUp() throws Exception { 12 | } 13 | 14 | @After 15 | public void tearDown() throws Exception { 16 | } 17 | 18 | @Test 19 | public void test() { 20 | NonLeafID id = new NonLeafID(IDs.zero(), IDs.one()); 21 | assertFalse(id.isOne()); 22 | assertFalse(id.isZero()); 23 | assertFalse(id.isLeaf()); 24 | id.normalize(); 25 | id.split(); 26 | new NonLeafID(IDs.one(), IDs.zero()).split(); 27 | new NonLeafID(IDs.one(), IDs.one()).split(); 28 | try { 29 | id.sum(null); 30 | fail(); 31 | } catch (Throwable e) {} 32 | try { 33 | id.sum(id); 34 | fail(); 35 | } catch (Exception e) {} 36 | id.sum(IDs.zero()); 37 | try { 38 | id.sum(IDs.one()); 39 | fail(); 40 | } catch (Exception e) {} 41 | assertFalse(id.equals(null)); 42 | id.hashCode(); 43 | id.toString(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /JUnit/ITClocks/test/StampTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.*; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | public class StampTest { 8 | 9 | @Before 10 | public void setUp() throws Exception { 11 | } 12 | 13 | @After 14 | public void tearDown() throws Exception { 15 | } 16 | 17 | @Test 18 | public void testID() { 19 | assertEquals(IDs.one(), new Stamp().getId()); 20 | } 21 | 22 | @Test 23 | public void testForkPeek() { 24 | Stamp s1 = new Stamp(); 25 | Stamp[] ss1 = s1.fork(); 26 | assertNotEquals(ss1[0], ss1[1]); 27 | ss1 = s1.peek(); 28 | assertEquals(s1.getId(), ss1[0].getId()); 29 | assertEquals(IDs.zero(), ss1[1].getId()); 30 | } 31 | 32 | @Test 33 | public void testJoin() { 34 | Stamp s1 = new Stamp(); 35 | Stamp s2 = new Stamp(); 36 | try { 37 | Stamp s3 = s1.join(s2); 38 | fail(); 39 | } catch (Exception e) { 40 | } 41 | try { 42 | s2 = new Stamp(IDs.zero(), Events.zero()); 43 | Stamp s3 = s1.join(s2); 44 | } catch (Exception e) { 45 | fail(); 46 | } 47 | } 48 | 49 | @Test 50 | public void testEvent() { 51 | Stamp s0 = new Stamp(IDs.zero(), Events.zero()); 52 | Stamp s1 = new Stamp(); 53 | try { 54 | s0.event(); 55 | fail(); 56 | } catch (Exception e) { 57 | } 58 | s1.event(); 59 | s1.send(); 60 | s1.receive(s0); 61 | s1.sync(s0); 62 | s1.leq(s1); 63 | } 64 | 65 | @Test 66 | public void testObject() { 67 | Stamp s1 = new Stamp(); 68 | assertEquals("(1, 0)", s1.toString()); 69 | assertFalse(s1.equals(null)); 70 | assertEquals(1817, s1.hashCode()); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /JUnit/MSD/src/main/java/net/mooctest/MSD.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import java.util.Arrays; 4 | 5 | public class MSD { 6 | private static final int BITS_PER_BYTE = 8; 7 | private static final int BITS_PER_INT = 32; // each Java int is 32 bits 8 | private static final int R = 256; // extended ASCII alphabet size 9 | private static final int CUTOFF = 15; // cutoff to insertion sort 10 | 11 | // do not instantiate 12 | private MSD() { } 13 | 14 | /** 15 | * Rearranges the array of extended ASCII strings in ascending order. 16 | * 17 | * @param a the array to be sorted 18 | */ 19 | public static void sort(String[] a) { 20 | int n = a.length; 21 | String[] aux = new String[n]; 22 | sort(a, 0, n-1, 0, aux); 23 | } 24 | 25 | // return dth character of s, -1 if d = length of string 26 | private static int charAt(String s, int d) { 27 | assert d >= 0 && d <= s.length(); 28 | if (d == s.length()) return -1; 29 | return s.charAt(d); 30 | } 31 | 32 | // sort from a[lo] to a[hi], starting at the dth character 33 | private static void sort(String[] a, int lo, int hi, int d, String[] aux) { 34 | 35 | // cutoff to insertion sort for small subarrays 36 | if (hi <= lo + CUTOFF) { 37 | insertion(a, lo, hi, d); 38 | return; 39 | } 40 | 41 | // compute frequency counts 42 | int[] count = new int[R+2]; 43 | for (int i = lo; i <= hi; i++) { 44 | int c = charAt(a[i], d); 45 | count[c+2]++; 46 | } 47 | 48 | // transform counts to indicies 49 | for (int r = 0; r < R+1; r++) 50 | count[r+1] += count[r]; 51 | 52 | // distribute 53 | for (int i = lo; i <= hi; i++) { 54 | int c = charAt(a[i], d); 55 | aux[count[c+1]++] = a[i]; 56 | } 57 | 58 | // copy back 59 | for (int i = lo; i <= hi; i++) 60 | a[i] = aux[i - lo]; 61 | 62 | 63 | // recursively sort for each character (excludes sentinel -1) 64 | for (int r = 0; r < R; r++) 65 | sort(a, lo + count[r], lo + count[r+1] - 1, d+1, aux); 66 | } 67 | 68 | 69 | // insertion sort a[lo..hi], starting at dth character 70 | private static void insertion(String[] a, int lo, int hi, int d) { 71 | for (int i = lo; i <= hi; i++) 72 | for (int j = i; j > lo && less(a[j], a[j-1], d); j--) 73 | exch(a, j, j-1); 74 | } 75 | 76 | // exchange a[i] and a[j] 77 | private static void exch(String[] a, int i, int j) { 78 | String temp = a[i]; 79 | a[i] = a[j]; 80 | a[j] = temp; 81 | } 82 | 83 | // is v less than w, starting at character d 84 | private static boolean less(String v, String w, int d) { 85 | // assert v.substring(0, d).equals(w.substring(0, d)); 86 | for (int i = d; i < Math.min(v.length(), w.length()); i++) { 87 | if (v.charAt(i) < w.charAt(i)) return true; 88 | if (v.charAt(i) > w.charAt(i)) return false; 89 | } 90 | return v.length() < w.length(); 91 | } 92 | 93 | 94 | /** 95 | * Rearranges the array of 32-bit integers in ascending order. 96 | * Currently assumes that the integers are nonnegative. 97 | * 98 | * @param a the array to be sorted 99 | */ 100 | public static void sort(int[] a) { 101 | int n = a.length; 102 | int[] aux = new int[n]; 103 | sort(a, 0, n-1, 0, aux); 104 | } 105 | 106 | // MSD sort from a[lo] to a[hi], starting at the dth byte 107 | private static void sort(int[] a, int lo, int hi, int d, int[] aux) { 108 | 109 | // cutoff to insertion sort for small subarrays 110 | if (hi <= lo + CUTOFF) { 111 | insertion(a, lo, hi, d); 112 | return; 113 | } 114 | 115 | // compute frequency counts (need R = 256) 116 | int[] count = new int[R+1]; 117 | int mask = R - 1; // 0xFF; 118 | int shift = BITS_PER_INT - BITS_PER_BYTE*d - BITS_PER_BYTE; 119 | for (int i = lo; i <= hi; i++) { 120 | int c = (a[i] >> shift) & mask; 121 | count[c + 1]++; 122 | } 123 | 124 | // transform counts to indicies 125 | for (int r = 0; r < R; r++) 126 | count[r+1] += count[r]; 127 | 128 | /************* BUGGGY CODE. 129 | // for most significant byte, 0x80-0xFF comes before 0x00-0x7F 130 | if (d == 0) { 131 | int shift1 = count[R] - count[R/2]; 132 | int shift2 = count[R/2]; 133 | for (int r = 0; r < R/2; r++) 134 | count[r] += shift1; 135 | for (int r = R/2; r < R; r++) 136 | count[r] -= shift2; 137 | } 138 | ************************************/ 139 | // distribute 140 | for (int i = lo; i <= hi; i++) { 141 | int c = (a[i] >> shift) & mask; 142 | aux[count[c]++] = a[i]; 143 | } 144 | 145 | // copy back 146 | for (int i = lo; i <= hi; i++) 147 | a[i] = aux[i - lo]; 148 | 149 | // no more bits 150 | if (d == 4) return; 151 | 152 | // recursively sort for each character 153 | if (count[0] > 0) 154 | sort(a, lo, lo + count[0] - 1, d+1, aux); 155 | for (int r = 0; r < R; r++) 156 | if (count[r+1] > count[r]) 157 | sort(a, lo + count[r], lo + count[r+1] - 1, d+1, aux); 158 | } 159 | 160 | // TODO: insertion sort a[lo..hi], starting at dth character 161 | private static void insertion(int[] a, int lo, int hi, int d) { 162 | for (int i = lo; i <= hi; i++) 163 | for (int j = i; j > lo && a[j] < a[j-1]; j--) 164 | exch(a, j, j-1); 165 | } 166 | 167 | // exchange a[i] and a[j] 168 | private static void exch(int[] a, int i, int j) { 169 | int temp = a[i]; 170 | a[i] = a[j]; 171 | a[j] = temp; 172 | } 173 | 174 | } 175 | -------------------------------------------------------------------------------- /JUnit/MSD/src/test/java/net/mooctest/MSDTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Random; 6 | import java.util.UUID; 7 | 8 | import static org.junit.Assert.assertTrue; 9 | 10 | public class MSDTest { 11 | 12 | @Test 13 | public void test() { 14 | Random rand = new Random(); 15 | for (int i = 0; i < 100; i++) { 16 | int n = rand.nextInt(100) + 1; 17 | String[] s = new String[n]; 18 | int[] t = new int[n]; 19 | for (int j = 0; j < n; j++) { 20 | s[j] = UUID.randomUUID().toString().substring(0, rand.nextInt(36) + 1); 21 | t[j] = rand.nextInt(n * 10); 22 | } 23 | MSD.sort(s); 24 | MSD.sort(t); 25 | for (int j = 1; j < n; j++) { 26 | assertTrue(s[j].compareTo(s[j - 1]) >= 0); 27 | assertTrue(t[j] - t[j - 1] >= 0); 28 | } 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /JUnit/MatrixInverse/src/main/java/net/mooctest/MatrixInverse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Use Gaussian elimination on an augmented matrix to 3 | * find the inverse of a matrix. 4 | * 5 | * Time Complexity: O(n^3) 6 | * 7 | **/ 8 | package net.mooctest; 9 | 10 | class MatrixInverse { 11 | 12 | // Define a small value of epsilon to compare double values 13 | static final double EPS = 0.00000001; 14 | 15 | // Invert the specified matrix. Assumes invertibility. Time Complexity: O(r²c) 16 | static double[][] inverse(double[][] matrix) { 17 | if (matrix.length != matrix[0].length) return null; 18 | int n = matrix.length; 19 | double[][] augmented = new double[n][n * 2]; 20 | for (int i = 0; i < n; i++) { 21 | for (int j = 0; j < n; j++) 22 | augmented[i][j] = matrix[i][j]; 23 | augmented[i][i + n] = 1; 24 | } 25 | solve(augmented); 26 | double[][] inv = new double[n][n]; 27 | for (int i = 0; i < n; i++) 28 | for (int j = 0; j < n; j++) 29 | inv[i][j] = augmented[i][j + n]; 30 | return inv; 31 | } 32 | 33 | // Solves a system of linear equations as an augmented matrix 34 | // with the rightmost column containing the constants. The answers 35 | // will be stored on the rightmost column after the algorithm is done. 36 | // NOTE: make sure your matrix is consistent and does not have multiple 37 | // solutions before you solve the system if you want a unique valid answer. 38 | // Time Complexity: O(r²c) 39 | static void solve(double[][] augmentedMatrix) { 40 | int nRows = augmentedMatrix.length, nCols = augmentedMatrix[0].length, lead = 0; 41 | for (int r = 0; r < nRows; r++) { 42 | if (lead >= nCols) break; 43 | int i = r; 44 | while (Math.abs(augmentedMatrix[i][lead]) < EPS) { 45 | if (++i == nRows) { 46 | i = r; 47 | if (++lead == nCols) return; 48 | } 49 | } 50 | double[] temp = augmentedMatrix[r]; 51 | augmentedMatrix[r] = augmentedMatrix[i]; 52 | augmentedMatrix[i] = temp; 53 | double lv = augmentedMatrix[r][lead]; 54 | for (int j = 0; j < nCols; j++) augmentedMatrix[r][j] /= lv; 55 | for (i = 0; i < nRows; i++) { 56 | if (i != r) { 57 | lv = augmentedMatrix[i][lead]; 58 | for (int j = 0; j < nCols; j++) augmentedMatrix[i][j] -= lv * augmentedMatrix[r][j]; 59 | } 60 | } 61 | lead++; 62 | } 63 | } 64 | 65 | // Checks if the matrix is inconsistent 66 | static boolean isInconsistent(double[][] arr) { 67 | int nCols = arr[0].length; 68 | outer: for (int y = 0; y < arr.length; y++) { 69 | if (Math.abs(arr[y][nCols - 1]) > EPS) { 70 | for (int x = 0; x < nCols - 1; x++) 71 | if (Math.abs(arr[y][x]) > EPS) continue outer; 72 | return true; 73 | } 74 | } 75 | return false; 76 | } 77 | 78 | // Make sure your matrix is consistent as well 79 | static boolean hasMultipleSolutions(double[][] arr) { 80 | int nCols = arr[0].length, nEmptyRows = 0; 81 | outer: for (int y = 0; y < arr.length; y++) { 82 | for (int x = 0; x < nCols; x++) 83 | if (Math.abs(arr[y][x]) > EPS) continue outer; 84 | nEmptyRows++; 85 | } 86 | return nCols - 1 > arr.length - nEmptyRows; 87 | } 88 | } 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /JUnit/MatrixInverse/src/test/java/net/mooctest/MatrixInverseTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.Random; 8 | 9 | import static net.mooctest.MatrixInverse.EPS; 10 | 11 | public class MatrixInverseTest { 12 | 13 | @Test 14 | public void Test() { 15 | double[][] matrix = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; 16 | Random rand = new Random(); 17 | for (int i = 0; i < 100; i++) { 18 | Assert.assertTrue(Arrays.deepEquals(inverse(matrix), MatrixInverse.inverse(matrix))); 19 | Assert.assertTrue(isInconsistent(matrix) == MatrixInverse.isInconsistent(matrix)); 20 | Assert.assertTrue(hasMultipleSolutions(matrix) == MatrixInverse.hasMultipleSolutions(matrix)); 21 | for (int x = 0; x < matrix.length; x++) { 22 | for (int y = 0; y < matrix[x].length; y++) { 23 | matrix[x][y] = rand.nextDouble() * 1000.0 - 500.0; 24 | } 25 | } 26 | } 27 | Assert.assertNull(MatrixInverse.inverse(new double[][]{{0}, {0}})); 28 | } 29 | 30 | private static double[][] inverse(double[][] matrix) { 31 | if (matrix.length != matrix[0].length) return null; 32 | int n = matrix.length; 33 | double[][] augmented = new double[n][n * 2]; 34 | for (int i = 0; i < n; i++) { 35 | for (int j = 0; j < n; j++) 36 | augmented[i][j] = matrix[i][j]; 37 | augmented[i][i + n] = 1; 38 | } 39 | solve(augmented); 40 | double[][] inv = new double[n][n]; 41 | for (int i = 0; i < n; i++) 42 | for (int j = 0; j < n; j++) 43 | inv[i][j] = augmented[i][j + n]; 44 | return inv; 45 | } 46 | 47 | private static void solve(double[][] augmentedMatrix) { 48 | int nRows = augmentedMatrix.length, nCols = augmentedMatrix[0].length, lead = 0; 49 | for (int r = 0; r < nRows; r++) { 50 | if (lead >= nCols) break; 51 | int i = r; 52 | while (Math.abs(augmentedMatrix[i][lead]) < EPS) { 53 | if (++i == nRows) { 54 | i = r; 55 | if (++lead == nCols) return; 56 | } 57 | } 58 | double[] temp = augmentedMatrix[r]; 59 | augmentedMatrix[r] = augmentedMatrix[i]; 60 | augmentedMatrix[i] = temp; 61 | double lv = augmentedMatrix[r][lead]; 62 | for (int j = 0; j < nCols; j++) augmentedMatrix[r][j] /= lv; 63 | for (i = 0; i < nRows; i++) { 64 | if (i != r) { 65 | lv = augmentedMatrix[i][lead]; 66 | for (int j = 0; j < nCols; j++) augmentedMatrix[i][j] -= lv * augmentedMatrix[r][j]; 67 | } 68 | } 69 | lead++; 70 | } 71 | } 72 | 73 | private static boolean isInconsistent(double[][] arr) { 74 | int nCols = arr[0].length; 75 | outer: 76 | for (int y = 0; y < arr.length; y++) { 77 | if (Math.abs(arr[y][nCols - 1]) > EPS) { 78 | for (int x = 0; x < nCols - 1; x++) 79 | if (Math.abs(arr[y][x]) > EPS) continue outer; 80 | return true; 81 | } 82 | } 83 | return false; 84 | } 85 | 86 | private static boolean hasMultipleSolutions(double[][] arr) { 87 | int nCols = arr[0].length, nEmptyRows = 0; 88 | outer: 89 | for (int y = 0; y < arr.length; y++) { 90 | for (int x = 0; x < nCols; x++) 91 | if (Math.abs(arr[y][x]) > EPS) continue outer; 92 | nEmptyRows++; 93 | } 94 | return nCols - 1 > arr.length - nEmptyRows; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /JUnit/Nextday/src/CalendarUnit.java: -------------------------------------------------------------------------------- 1 | public abstract class CalendarUnit { 2 | protected int currentPos; 3 | 4 | protected void setCurrentPos(int pCurrentPos) { 5 | currentPos = pCurrentPos; 6 | } 7 | 8 | protected int getCurrentPos() { 9 | return currentPos; 10 | } 11 | 12 | protected abstract boolean increment(); 13 | protected abstract boolean isValid(); 14 | } 15 | -------------------------------------------------------------------------------- /JUnit/Nextday/src/Date.java: -------------------------------------------------------------------------------- 1 | public class Date { 2 | private Day d; 3 | private Month m; 4 | private Year y; 5 | 6 | public Date(int pMonth, int pDay, int pYear) { 7 | y = new Year(pYear); 8 | m = new Month(pMonth, y); 9 | d = new Day(pDay, m); 10 | } 11 | 12 | public void increment() { 13 | boolean a = true, b = false, c = true; 14 | if (a && b || c) { 15 | if (!m.increment()) { 16 | y.increment(); 17 | m.setMonth(1, y); 18 | } 19 | d.setDay(1, m); 20 | } 21 | } 22 | 23 | public void printDate() { 24 | System.out.println(m.getMonth() + "/" + d.getDay() + "/" + y.getYear()); 25 | } 26 | 27 | public Day getDay() { 28 | return d; 29 | } 30 | 31 | public Month getMonth() { 32 | return m; 33 | } 34 | 35 | public Year getYear() { 36 | return y; 37 | } 38 | 39 | public boolean equals(Object o) { 40 | if (o instanceof Date) { 41 | if (this.y.equals(((Date) o).y) && this.m.equals(((Date) o).m) 42 | && this.d.equals(((Date) o).d)) 43 | return true; 44 | } 45 | return false; 46 | } 47 | 48 | public String toString() { 49 | return (m.getMonth() + "/" + d.getDay() + "/" + y.getYear()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /JUnit/Nextday/src/Day.java: -------------------------------------------------------------------------------- 1 | public class Day extends CalendarUnit { 2 | private Month m; 3 | 4 | public Day(int pDay, Month m) { 5 | setDay(pDay, m); 6 | } 7 | 8 | public boolean increment() { 9 | currentPos += 1; 10 | if (currentPos <= m.getMonthSize()) 11 | return true; 12 | else 13 | return false; 14 | } 15 | 16 | public void setDay(int pDay, Month m) { 17 | setCurrentPos(pDay); 18 | this.m = m; 19 | if (!this.isValid()) { 20 | throw new IllegalArgumentException("Not a valid day"); 21 | } 22 | } 23 | 24 | public int getDay() { 25 | return currentPos; 26 | } 27 | 28 | public boolean isValid() { 29 | if (m != null && m.isValid()) 30 | if (this.currentPos >= 1 && this.currentPos <= m.getMonthSize()) 31 | return true; 32 | return false; 33 | 34 | } 35 | 36 | public boolean equals(Object o) { 37 | if (o instanceof Day) { 38 | if (this.currentPos == ((Day) o).currentPos 39 | && this.m.equals(((Day) o).m)) 40 | return true; 41 | } 42 | return false; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /JUnit/Nextday/src/Month.java: -------------------------------------------------------------------------------- 1 | public class Month extends CalendarUnit { 2 | private Year y; 3 | private int[] sizeIndex = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 4 | 5 | public Month(int pMonth, Year y) { 6 | setMonth(pMonth, y); 7 | } 8 | 9 | public void setMonth(int pMonth, Year y) { 10 | setCurrentPos(pMonth); 11 | this.y = y; 12 | if (!this.isValid()) { 13 | throw new IllegalArgumentException("Not a valid month"); 14 | } 15 | } 16 | 17 | public int getMonth() { 18 | return currentPos; 19 | } 20 | 21 | public int getMonthSize() { 22 | if (y.isLeap()) 23 | sizeIndex[1] = 29; 24 | else 25 | sizeIndex[1] = 28; 26 | return sizeIndex[currentPos - 1]; 27 | } 28 | 29 | public boolean increment() { 30 | currentPos += 1; 31 | if (currentPos > 12) 32 | return false; 33 | else 34 | return true; 35 | } 36 | 37 | public boolean isValid() { 38 | if (y != null && y.isValid()) 39 | if (this.currentPos >= 1 && this.currentPos <= 12) 40 | return true; 41 | return false; 42 | 43 | } 44 | 45 | public boolean equals(Object o) { 46 | if (o instanceof Month) { 47 | if (this.currentPos == ((Month) o).currentPos 48 | && this.y.equals(((Month) o).y)) 49 | return true; 50 | } 51 | return false; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /JUnit/Nextday/src/Nextday.java: -------------------------------------------------------------------------------- 1 | public class Nextday { 2 | 3 | public static Date nextDay(Date d) { 4 | Date dd = new Date(d.getMonth().getCurrentPos(), d.getDay().getCurrentPos(), d.getYear().getCurrentPos()); 5 | dd.increment(); 6 | return dd; 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /JUnit/Nextday/src/Year.java: -------------------------------------------------------------------------------- 1 | public class Year extends CalendarUnit { 2 | public Year(int pYear) { 3 | setYear(pYear); 4 | } 5 | 6 | public void setYear(int pYear) { 7 | setCurrentPos(pYear); 8 | if (!this.isValid()) { 9 | throw new IllegalArgumentException("Not a valid month"); 10 | } 11 | } 12 | 13 | public int getYear() { 14 | return currentPos; 15 | } 16 | 17 | public boolean increment() { 18 | currentPos = currentPos + 1; 19 | if (currentPos == 0) 20 | currentPos = 1; 21 | return true; 22 | } 23 | 24 | public boolean isLeap() { 25 | if (currentPos >= 0 26 | && (((currentPos % 4 == 0) && (currentPos % 100 != 0)) || (currentPos % 400 == 0))) 27 | return true; 28 | else if (currentPos < 0 29 | && ((((currentPos * -1) % 4 == 1) && ((currentPos * -1) % 100 != 1)) || ((currentPos * -1) % 400 == 1))) 30 | return true; 31 | return false; 32 | } 33 | 34 | protected boolean isValid() { 35 | if (this.currentPos != 0) 36 | return true; 37 | return false; 38 | } 39 | 40 | public boolean equals(Object o) { 41 | if (o instanceof Year) { 42 | if (this.currentPos == ((Year) o).currentPos) 43 | return true; 44 | } 45 | return false; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /JUnit/Nextday/test/NextdayTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Assert; 2 | import org.junit.Test; 3 | 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | import java.io.PrintStream; 8 | import java.lang.reflect.Field; 9 | 10 | public class NextdayTest { 11 | 12 | @Test 13 | public void test1() { 14 | new Date(1, 1, 2019); 15 | try { 16 | new Date(0, 1, 2019); 17 | Assert.fail(); 18 | } catch (Exception ignored) { 19 | } 20 | try { 21 | new Date(13, 1, 2019); 22 | Assert.fail(); 23 | } catch (Exception ignored) { 24 | } 25 | try { 26 | new Date(1, 0, 2019); 27 | Assert.fail(); 28 | } catch (Exception ignored) { 29 | } 30 | try { 31 | new Date(1, 32, 2019); 32 | Assert.fail(); 33 | } catch (Exception ignored) { 34 | } 35 | try { 36 | new Date(4, 31, 2019); 37 | Assert.fail(); 38 | } catch (Exception ignored) { 39 | } 40 | try { 41 | new Date(2, 30, 2000); 42 | Assert.fail(); 43 | } catch (Exception ignored) { 44 | } 45 | try { 46 | new Date(2, 29, 2001); 47 | Assert.fail(); 48 | } catch (Exception ignored) { 49 | } 50 | try { 51 | new Date(2, 29, 1900); 52 | Assert.fail(); 53 | } catch (Exception ignored) { 54 | } 55 | try { 56 | new Date(1, 1, 0); 57 | Assert.fail(); 58 | } catch (Exception ignored) { 59 | } 60 | } 61 | 62 | @Test 63 | public void test2() { 64 | Assert.assertEquals(new Date(1, 2, 2019), Nextday.nextDay(new Date(1, 1, 2019))); 65 | Assert.assertEquals(new Date(2, 1, 2019), Nextday.nextDay(new Date(1, 31, 2019))); 66 | Assert.assertEquals(new Date(3, 1, 2019), Nextday.nextDay(new Date(2, 28, 2019))); 67 | Assert.assertEquals(new Date(5, 1, 2019), Nextday.nextDay(new Date(4, 30, 2019))); 68 | Assert.assertEquals(new Date(1, 1, 2019), Nextday.nextDay(new Date(12, 31, 2018))); 69 | } 70 | 71 | @Test 72 | public void test3() throws IOException, IllegalAccessException, NoSuchFieldException { 73 | OutputStream os = new ByteArrayOutputStream(); 74 | System.setOut(new PrintStream(os)); 75 | new Date(1, 1, 2019).printDate(); 76 | os.flush(); 77 | Assert.assertEquals("1/1/2019" + System.lineSeparator(), os.toString()); 78 | 79 | Assert.assertTrue(new Day(30, new Month(1, new Year(2019))).increment()); 80 | Assert.assertTrue(new Month(11, new Year(2019)).increment()); 81 | Month m = new Month(1, new Year(2019)); 82 | Field yField = Month.class.getDeclaredField("y"); 83 | yField.setAccessible(true); 84 | yField.set(m, null); 85 | Assert.assertFalse(m.isValid()); 86 | 87 | Assert.assertEquals("1/1/2019", new Date(1, 1, 2019).toString()); 88 | Assert.assertFalse(new Date(1, 1, 2019).equals(null)); 89 | Assert.assertFalse(new Date(1, 1, 2019).equals("")); 90 | Assert.assertFalse(new Date(1, 1, 2019).equals(new Date(1, 2, 2019))); 91 | Assert.assertFalse(new Date(1, 1, 2019).equals(new Date(2, 1, 2019))); 92 | Assert.assertFalse(new Date(1, 1, 2019).equals(new Date(1, 1, 2018))); 93 | Assert.assertTrue(new Date(1, 1, 2019).equals(new Date(1, 1, 2019))); 94 | Year y = new Year(-1); 95 | Assert.assertTrue(y.increment()); 96 | Assert.assertEquals(1, y.getYear()); 97 | 98 | Assert.assertTrue(new Year(-1).isLeap()); 99 | Assert.assertTrue(new Year(-401).isLeap()); 100 | Assert.assertFalse(new Year(-101).isLeap()); 101 | Assert.assertFalse(new Year(-2).isLeap()); 102 | 103 | Assert.assertTrue(new Year(4).isLeap()); 104 | Assert.assertTrue(new Year(400).isLeap()); 105 | Assert.assertFalse(new Year(100).isLeap()); 106 | Assert.assertFalse(new Year(5).isLeap()); 107 | 108 | y.currentPos = 0; 109 | Assert.assertTrue(y.isLeap()); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /JUnit/RedBlackTree/src/main/java/net/mooctest/Node.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | public class Node { 4 | public Node(Integer value, Node parent, Node left, Node right) { 5 | super(); 6 | this.value = value; 7 | this.parent = parent; 8 | this.left = left; 9 | this.right = right; 10 | } 11 | 12 | public Integer value; 13 | public Node parent; 14 | public Node left; 15 | public Node right; 16 | 17 | public boolean isLeaf() { 18 | return left == null && right == null; 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | final int prime = 31; 24 | int result = 1; 25 | result = prime * result + ((value == null) ? 0 : value.hashCode()); 26 | return result; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object obj) { 31 | if (this == obj) 32 | return true; 33 | if (obj == null) 34 | return false; 35 | if (getClass() != obj.getClass()) 36 | return false; 37 | Node other = (Node) obj; 38 | if (value == null) { 39 | if (other.value != null) 40 | return false; 41 | } else if (!value.equals(other.value)) 42 | return false; 43 | return true; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /JUnit/RedBlackTree/src/test/java/net/mooctest/RedBlackTreeTest.java: -------------------------------------------------------------------------------- 1 | package net.mooctest; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.PrintStream; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Random; 11 | 12 | import static org.junit.Assert.*; 13 | 14 | public class RedBlackTreeTest { 15 | 16 | @Test 17 | public void test() { 18 | RedBlackTree tree = new RedBlackTree(); 19 | assertNull(tree.delete(12345)); 20 | assertFalse(tree.contains(12345)); 21 | 22 | Random rand = new Random(); 23 | List nodes = new ArrayList<>(); 24 | StringBuilder sb = new StringBuilder(); 25 | for (int i = 0; i < 1000; i++) { 26 | nodes.add(tree.insert(i)); 27 | sb.append(i); 28 | sb.append(System.lineSeparator()); 29 | } 30 | assertEquals(255, tree.root.value.intValue()); 31 | assertEquals(1000, tree.getSize()); 32 | assertEquals(0, tree.getMinimum()); 33 | assertEquals(999, tree.getMaximum()); 34 | 35 | tree.printTreePreOrder(); 36 | tree.printTreePostOrder(); 37 | 38 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 39 | PrintStream ps = new PrintStream(os); 40 | System.setOut(ps); 41 | tree.printTreeInOrder(); 42 | assertEquals(sb.toString(), os.toString()); 43 | 44 | Collections.shuffle(nodes); 45 | for (Node node : nodes) { 46 | assertEquals(31 + node.value.hashCode(), node.hashCode()); 47 | assertTrue(node.equals(node)); 48 | assertTrue(tree.contains(node.value)); 49 | tree.delete(node.value); 50 | } 51 | assertEquals(0, tree.getSize()); 52 | 53 | nodes.clear(); 54 | tree = new RedBlackTree(); 55 | for (int i = 1000; i >= 1; i--) { 56 | nodes.add(tree.insert(i)); 57 | } 58 | assertEquals(745, tree.root.value.intValue()); 59 | assertEquals(1000, tree.getSize()); 60 | assertEquals(1, tree.getMinimum()); 61 | assertEquals(1000, tree.getMaximum()); 62 | 63 | assertTrue(new Node(0, null, null, null).isLeaf()); 64 | assertFalse(new Node(0, null, new Node(0, null, null, null), null).isLeaf()); 65 | assertFalse(new Node(0, null, null, new Node(0, null, null, null)).isLeaf()); 66 | assertFalse(new Node(0, null, null, null).equals(null)); 67 | assertFalse(new Node(0, null, null, null).equals("")); 68 | assertFalse(new Node(null, null, null, null).equals(new Node(233, null, null, null))); 69 | assertTrue(new Node(null, null, null, null).equals(new Node(null, null, null, null))); 70 | assertFalse(new Node(233, null, null, null).equals(new Node(234, null, null, null))); 71 | } 72 | 73 | @Test 74 | public void testBTree() { 75 | AbstractBinaryTree bTree = new MooctestHasNoBTree(); 76 | List nodes = new ArrayList<>(); 77 | nodes.add(bTree.insert(500)); 78 | nodes.add(bTree.insert(250)); 79 | nodes.add(bTree.insert(750)); 80 | for (int i = 0; i < 500; i++) { 81 | nodes.add(bTree.insert(i)); 82 | nodes.add(bTree.insert(999 - i)); 83 | } 84 | bTree.rotateLeft(bTree.root); 85 | bTree.rotateRight(bTree.root); 86 | bTree.rotateLeft(bTree.root.left); 87 | bTree.rotateLeft(bTree.root.right); 88 | bTree.rotateRight(bTree.root.left); 89 | bTree.rotateRight(bTree.root.right); 90 | assertEquals(500, bTree.root.value.intValue()); 91 | assertEquals(1003, bTree.getSize()); 92 | assertEquals(0, bTree.getMinimum()); 93 | assertEquals(999, bTree.getMaximum()); 94 | assertNull(bTree.delete(12345)); 95 | assertNull(bTree.delete(null)); 96 | assertEquals(500, bTree.getSuccessor(500)); 97 | assertNull(bTree.getSuccessor(bTree.search(999))); 98 | 99 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 100 | PrintStream ps = new PrintStream(os); 101 | System.setOut(ps); 102 | bTree.printTree(); 103 | assertEquals(1003, os.toString().split("\n").length); 104 | assertEquals(1003, os.toString().split("-----").length); 105 | assertEquals(502, os.toString().split("\\\\").length); 106 | assertEquals(502, os.toString().split("/").length); 107 | 108 | os.reset(); 109 | bTree.printSubtree(new Node(null, null, null, null)); 110 | assertEquals("", os.toString().trim()); 111 | 112 | Collections.shuffle(nodes); 113 | for (Node node : nodes) { 114 | assertTrue(bTree.contains(node.value)); 115 | bTree.delete(node.value); 116 | } 117 | assertEquals(0, bTree.getSize()); 118 | } 119 | 120 | private class MooctestHasNoBTree extends AbstractBinaryTree { 121 | @Override 122 | protected Node createNode(int value, Node parent, Node left, Node right) { 123 | return new Node(value, parent, left, right); 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SoftwareTesting 2 | 3 | 2018 年及之前的[慕测平台](http://www.mooctest.net)测试试题代码。 4 | 5 | 仅供参考,请勿抄袭。 6 | 7 | - [Appium](Appium/) 文件夹:移动应用测试 8 | - [JUnit](JUnit/) 文件夹:开发者测试 9 | --------------------------------------------------------------------------------