diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 000000000..e3233268f --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck diff --git a/AI Forward Chaining Resolution/ForwardChaining.java b/AI Forward Chaining Resolution/ForwardChaining.java new file mode 100644 index 000000000..b2af74e74 --- /dev/null +++ b/AI Forward Chaining Resolution/ForwardChaining.java @@ -0,0 +1,88 @@ +package forwardChaining; +import java.awt.Frame; +import java.util.*; + + +public class ForwardChaining { + static Scanner sc = new Scanner(System.in); + public static void main(String[] args) { + prln("Enter Number of Horn Clauses"); + int n = sc.nextInt(); + sc.nextLine(); + for(int i=0; i < n; i++) { // Iterate over number of Horn clause + String s = sc.nextLine(); //Takes a Horn Clause + + makeInferred(s.substring(0, s.indexOf("=>"))); + GlobalVar.head.put(s.substring(0, s.indexOf("=>")), s.substring(s.indexOf("=>")+2,s.length())); + } + prln("Enter Number of Agenda"); + int m = sc.nextInt(); + //sc.next(); + for(int i=0 ; i head = new HashMap(); + static Map inferred = new HashMap(); + static Map count = new HashMap(); + static Queue agenda = new LinkedList(); + } +} diff --git a/Arduino_Code/Arduino-IRremote/Contributing.md b/Arduino_Code/Arduino-IRremote/Contributing.md new file mode 100644 index 000000000..56409a9d2 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/Contributing.md @@ -0,0 +1,11 @@ +# Contribution Guidlines + +This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. The best way to ask for help or propose a new idea is to [create a new issue](https://github.com/z3t0/Arduino-IRremote/issues/new) while creating a Pull Request with your code changes allows you to share your own innovations with the rest of the community. + +The following are some guidelines to observe when creating issues or PRs: +- Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas +- [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets +- Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile: +- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library + +If there is any need to contact me then you can find my email on the README, I do not mind responding to emails but it would be in your own interests to create issues if you need help with the library as responses would be from a larger community with greater knowledge! \ No newline at end of file diff --git a/Arduino_Code/Arduino-IRremote/Contributors.md b/Arduino_Code/Arduino-IRremote/Contributors.md new file mode 100644 index 000000000..1bed7b6d4 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/Contributors.md @@ -0,0 +1,22 @@ +## Contributors +These are the active contributors of this project that you may contact if there is anything you need help with or if you have suggestions. + +- [z3t0](https://github.com/z3t0) : Active Contributor and currently also the main contributor. + * Email: zetoslab@gmail.com +- [shirriff](https://github.com/shirriff) : An amazing person who worked to create this awesome library and provide unending support +- [AnalysIR](https:/github.com/AnalysIR): Active contributor and is amazing with providing support! +- [Informatic](https://github.com/Informatic) : Active contributor +- [fmeschia](https://github.com/fmeschia) : Active contributor +- [PaulStoffregen](https://github.com/paulstroffregen) : Active contributor +- [crash7](https://github.com/crash7) : Active contributor +- [Neco777](https://github.com/neco777) : Active contributor +- [Lauszus](https://github.com/lauszus) : Active contributor +- [csBlueChip](https://github.com/csbluechip) : Active contributor, who contributed major and vital changes to the code base. +- [Sebazzz](https://github.com/sebazz): Contributor +- [lumbric](https://github.com/lumbric): Contributor +- [ElectricRCAircraftGuy](https://github.com/electricrcaircraftguy): Active Contributor +- [philipphenkel](https://github.com/philipphenkel): Active Contributor +- [MCUdude](https://github.com/MCUdude): Contributor +- [marcmerlin](https://github.com/marcmerlin): Contributor (ESP32 port) + +Note: This list is being updated constantly so please let [z3t0](https://github.com/z3t0) know if you have been missed. diff --git a/Arduino_Code/Arduino-IRremote/IRremote.cpp b/Arduino_Code/Arduino-IRremote/IRremote.cpp new file mode 100644 index 000000000..e811cfc7b --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/IRremote.cpp @@ -0,0 +1,200 @@ +//****************************************************************************** +// IRremote +// Version 2.0.1 June, 2015 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html +// +// Modified by Paul Stoffregen to support other boards and timers +// Modified by Mitra Ardron +// Added Sanyo and Mitsubishi controllers +// Modified Sony to spot the repeat codes that some Sony's send +// +// Interrupt code based on NECIRrcv by Joe Knapp +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 +// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ +// +// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +// LG added by Darryl Smith (based on the JVC protocol) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** + +// Defining IR_GLOBAL here allows us to declare the instantiation of global variables +#define IR_GLOBAL +# include "IRremote.h" +# include "IRremoteInt.h" +#undef IR_GLOBAL + +#ifndef IR_TIMER_USE_ESP32 +#include +#endif + + +//+============================================================================= +// The match functions were (apparently) originally MACROs to improve code speed +// (although this would have bloated the code) hence the names being CAPS +// A later release implemented debug output and so they needed to be converted +// to functions. +// I tried to implement a dual-compile mode (DEBUG/non-DEBUG) but for some +// reason, no matter what I did I could not get them to function as macros again. +// I have found a *lot* of bugs in the Arduino compiler over the last few weeks, +// and I am currently assuming that one of these bugs is my problem. +// I may revisit this code at a later date and look at the assembler produced +// in a hope of finding out what is going on, but for now they will remain as +// functions even in non-DEBUG mode +// +int MATCH (int measured, int desired) +{ + DBG_PRINT(F("Testing: ")); + DBG_PRINT(TICKS_LOW(desired), DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(measured, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(TICKS_HIGH(desired), DEC); + + bool passed = ((measured >= TICKS_LOW(desired)) && (measured <= TICKS_HIGH(desired))); + if (passed) + DBG_PRINTLN(F("?; passed")); + else + DBG_PRINTLN(F("?; FAILED")); + return passed; +} + +//+======================================================== +// Due to sensor lag, when received, Marks tend to be 100us too long +// +int MATCH_MARK (int measured_ticks, int desired_us) +{ + DBG_PRINT(F("Testing mark (actual vs desired): ")); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(F("us vs ")); + DBG_PRINT(desired_us, DEC); + DBG_PRINT("us"); + DBG_PRINT(": "); + DBG_PRINT(TICKS_LOW(desired_us + MARK_EXCESS) * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(TICKS_HIGH(desired_us + MARK_EXCESS) * USECPERTICK, DEC); + + bool passed = ((measured_ticks >= TICKS_LOW (desired_us + MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS))); + if (passed) + DBG_PRINTLN(F("?; passed")); + else + DBG_PRINTLN(F("?; FAILED")); + return passed; +} + +//+======================================================== +// Due to sensor lag, when received, Spaces tend to be 100us too short +// +int MATCH_SPACE (int measured_ticks, int desired_us) +{ + DBG_PRINT(F("Testing space (actual vs desired): ")); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(F("us vs ")); + DBG_PRINT(desired_us, DEC); + DBG_PRINT("us"); + DBG_PRINT(": "); + DBG_PRINT(TICKS_LOW(desired_us - MARK_EXCESS) * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(measured_ticks * USECPERTICK, DEC); + DBG_PRINT(F(" <= ")); + DBG_PRINT(TICKS_HIGH(desired_us - MARK_EXCESS) * USECPERTICK, DEC); + + bool passed = ((measured_ticks >= TICKS_LOW (desired_us - MARK_EXCESS)) + && (measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS))); + if (passed) + DBG_PRINTLN(F("?; passed")); + else + DBG_PRINTLN(F("?; FAILED")); + return passed; +} + +//+============================================================================= +// Interrupt Service Routine - Fires every 50uS +// TIMER2 interrupt code to collect raw data. +// Widths of alternating SPACE, MARK are recorded in rawbuf. +// Recorded in ticks of 50uS [microseconds, 0.000050 seconds] +// 'rawlen' counts the number of entries recorded so far. +// First entry is the SPACE between transmissions. +// As soon as a the first [SPACE] entry gets long: +// Ready is set; State switches to IDLE; Timing of SPACE continues. +// As soon as first MARK arrives: +// Gap width is recorded; Ready is cleared; New logging starts +// +#ifdef IR_TIMER_USE_ESP32 +void IRTimer() +#else +ISR (TIMER_INTR_NAME) +#endif +{ + TIMER_RESET; + + // Read if IR Receiver -> SPACE [xmt LED off] or a MARK [xmt LED on] + // digitalRead() is very slow. Optimisation is possible, but makes the code unportable + uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); + + irparams.timer++; // One more 50uS tick + if (irparams.rawlen >= RAWBUF) irparams.rcvstate = STATE_OVERFLOW ; // Buffer overflow + + switch(irparams.rcvstate) { + //...................................................................... + case STATE_IDLE: // In the middle of a gap + if (irdata == MARK) { + if (irparams.timer < GAP_TICKS) { // Not big enough to be a gap. + irparams.timer = 0; + + } else { + // Gap just ended; Record duration; Start recording transmission + irparams.overflow = false; + irparams.rawlen = 0; + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_MARK; + } + } + break; + //...................................................................... + case STATE_MARK: // Timing Mark + if (irdata == SPACE) { // Mark ended; Record time + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_SPACE; + } + break; + //...................................................................... + case STATE_SPACE: // Timing Space + if (irdata == MARK) { // Space just ended; Record time + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_MARK; + + } else if (irparams.timer > GAP_TICKS) { // Space + // A long Space, indicates gap between codes + // Flag the current code as ready for processing + // Switch to STOP + // Don't reset timer; keep counting Space width + irparams.rcvstate = STATE_STOP; + } + break; + //...................................................................... + case STATE_STOP: // Waiting; Measuring Gap + if (irdata == MARK) irparams.timer = 0 ; // Reset gap timer + break; + //...................................................................... + case STATE_OVERFLOW: // Flag up a read overflow; Stop the State Machine + irparams.overflow = true; + irparams.rcvstate = STATE_STOP; + break; + } + + // If requested, flash LED while receiving IR data + if (irparams.blinkflag) { + if (irdata == MARK) + if (irparams.blinkpin) digitalWrite(irparams.blinkpin, HIGH); // Turn user defined pin LED on + else BLINKLED_ON() ; // if no user defined LED pin, turn default LED pin for the hardware on + else if (irparams.blinkpin) digitalWrite(irparams.blinkpin, LOW); // Turn user defined pin LED on + else BLINKLED_OFF() ; // if no user defined LED pin, turn default LED pin for the hardware on + } +} diff --git a/Arduino_Code/Arduino-IRremote/IRremote.h b/Arduino_Code/Arduino-IRremote/IRremote.h new file mode 100644 index 000000000..fe1a87029 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/IRremote.h @@ -0,0 +1,344 @@ + +//****************************************************************************** +// IRremote +// Version 2.0.1 June, 2015 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html +// Edited by Mitra to add new controller SANYO +// +// Interrupt code based on NECIRrcv by Joe Knapp +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 +// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ +// +// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +// LG added by Darryl Smith (based on the JVC protocol) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** + +#ifndef IRremote_h +#define IRremote_h + +//------------------------------------------------------------------------------ +// The ISR header contains several useful macros the user may wish to use +// +#include "IRremoteInt.h" + +//------------------------------------------------------------------------------ +// Supported IR protocols +// Each protocol you include costs memory and, during decode, costs time +// Disable (set to 0) all the protocols you do not need/want! +// +#define DECODE_RC5 1 +#define SEND_RC5 1 + +#define DECODE_RC6 1 +#define SEND_RC6 1 + +#define DECODE_NEC 1 +#define SEND_NEC 1 + +#define DECODE_SONY 1 +#define SEND_SONY 1 + +#define DECODE_PANASONIC 1 +#define SEND_PANASONIC 1 + +#define DECODE_JVC 1 +#define SEND_JVC 1 + +#define DECODE_SAMSUNG 1 +#define SEND_SAMSUNG 1 + +#define DECODE_WHYNTER 1 +#define SEND_WHYNTER 1 + +#define DECODE_AIWA_RC_T501 1 +#define SEND_AIWA_RC_T501 1 + +#define DECODE_LG 1 +#define SEND_LG 1 + +#define DECODE_SANYO 1 +#define SEND_SANYO 0 // NOT WRITTEN + +#define DECODE_MITSUBISHI 1 +#define SEND_MITSUBISHI 0 // NOT WRITTEN + +#define DECODE_DISH 0 // NOT WRITTEN +#define SEND_DISH 1 + +#define DECODE_SHARP 0 // NOT WRITTEN +#define SEND_SHARP 1 + +#define DECODE_DENON 1 +#define SEND_DENON 1 + +#define DECODE_PRONTO 0 // This function doe not logically make sense +#define SEND_PRONTO 1 + +#define DECODE_LEGO_PF 0 // NOT WRITTEN +#define SEND_LEGO_PF 1 + +//------------------------------------------------------------------------------ +// When sending a Pronto code we request to send either the "once" code +// or the "repeat" code +// If the code requested does not exist we can request to fallback on the +// other code (the one we did not explicitly request) +// +// I would suggest that "fallback" will be the standard calling method +// The last paragraph on this page discusses the rationale of this idea: +// http://www.remotecentral.com/features/irdisp2.htm +// +#define PRONTO_ONCE false +#define PRONTO_REPEAT true +#define PRONTO_FALLBACK true +#define PRONTO_NOFALLBACK false + +//------------------------------------------------------------------------------ +// An enumerated list of all supported formats +// You do NOT need to remove entries from this list when disabling protocols! +// +typedef + enum { + UNKNOWN = -1, + UNUSED = 0, + RC5, + RC6, + NEC, + SONY, + PANASONIC, + JVC, + SAMSUNG, + WHYNTER, + AIWA_RC_T501, + LG, + SANYO, + MITSUBISHI, + DISH, + SHARP, + DENON, + PRONTO, + LEGO_PF, + } +decode_type_t; + +//------------------------------------------------------------------------------ +// Set DEBUG to 1 for lots of lovely debug output +// +#define DEBUG 0 + +//------------------------------------------------------------------------------ +// Debug directives +// +#if DEBUG +# define DBG_PRINT(...) Serial.print(__VA_ARGS__) +# define DBG_PRINTLN(...) Serial.println(__VA_ARGS__) +#else +# define DBG_PRINT(...) +# define DBG_PRINTLN(...) +#endif + +//------------------------------------------------------------------------------ +// Mark & Space matching functions +// +int MATCH (int measured, int desired) ; +int MATCH_MARK (int measured_ticks, int desired_us) ; +int MATCH_SPACE (int measured_ticks, int desired_us) ; + +//------------------------------------------------------------------------------ +// Results returned from the decoder +// +class decode_results +{ + public: + decode_type_t decode_type; // UNKNOWN, NEC, SONY, RC5, ... + unsigned int address; // Used by Panasonic & Sharp [16-bits] + unsigned long value; // Decoded value [max 32-bits] + int bits; // Number of bits in decoded value + volatile unsigned int *rawbuf; // Raw intervals in 50uS ticks + int rawlen; // Number of records in rawbuf + int overflow; // true iff IR raw code too long +}; + +//------------------------------------------------------------------------------ +// Decoded value for NEC when a repeat code is received +// +#define REPEAT 0xFFFFFFFF + +//------------------------------------------------------------------------------ +// Main class for receiving IR +// +class IRrecv +{ + public: + IRrecv (int recvpin) ; + IRrecv (int recvpin, int blinkpin); + + void blink13 (int blinkflag) ; + int decode (decode_results *results) ; + void enableIRIn ( ) ; + bool isIdle ( ) ; + void resume ( ) ; + + private: + long decodeHash (decode_results *results) ; + int compare (unsigned int oldval, unsigned int newval) ; + + //...................................................................... +# if (DECODE_RC5 || DECODE_RC6) + // This helper function is shared by RC5 and RC6 + int getRClevel (decode_results *results, int *offset, int *used, int t1) ; +# endif +# if DECODE_RC5 + bool decodeRC5 (decode_results *results) ; +# endif +# if DECODE_RC6 + bool decodeRC6 (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_NEC + bool decodeNEC (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_SONY + bool decodeSony (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_PANASONIC + bool decodePanasonic (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_JVC + bool decodeJVC (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_SAMSUNG + bool decodeSAMSUNG (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_WHYNTER + bool decodeWhynter (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_AIWA_RC_T501 + bool decodeAiwaRCT501 (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_LG + bool decodeLG (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_SANYO + bool decodeSanyo (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_MITSUBISHI + bool decodeMitsubishi (decode_results *results) ; +# endif + //...................................................................... +# if DECODE_DISH + bool decodeDish (decode_results *results) ; // NOT WRITTEN +# endif + //...................................................................... +# if DECODE_SHARP + bool decodeSharp (decode_results *results) ; // NOT WRITTEN +# endif + //...................................................................... +# if DECODE_DENON + bool decodeDenon (decode_results *results) ; +# endif +//...................................................................... +# if DECODE_LEGO_PF + bool decodeLegoPowerFunctions (decode_results *results) ; +# endif +} ; + +//------------------------------------------------------------------------------ +// Main class for sending IR +// +class IRsend +{ + public: + IRsend () { } + + void custom_delay_usec (unsigned long uSecs); + void enableIROut (int khz) ; + void mark (unsigned int usec) ; + void space (unsigned int usec) ; + void sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) ; + + //...................................................................... +# if SEND_RC5 + void sendRC5 (unsigned long data, int nbits) ; +# endif +# if SEND_RC6 + void sendRC6 (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_NEC + void sendNEC (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_SONY + void sendSony (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_PANASONIC + void sendPanasonic (unsigned int address, unsigned long data) ; +# endif + //...................................................................... +# if SEND_JVC + // JVC does NOT repeat by sending a separate code (like NEC does). + // The JVC protocol repeats by skipping the header. + // To send a JVC repeat signal, send the original code value + // and set 'repeat' to true + void sendJVC (unsigned long data, int nbits, bool repeat) ; +# endif + //...................................................................... +# if SEND_SAMSUNG + void sendSAMSUNG (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_WHYNTER + void sendWhynter (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_AIWA_RC_T501 + void sendAiwaRCT501 (int code) ; +# endif + //...................................................................... +# if SEND_LG + void sendLG (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_SANYO + void sendSanyo ( ) ; // NOT WRITTEN +# endif + //...................................................................... +# if SEND_MISUBISHI + void sendMitsubishi ( ) ; // NOT WRITTEN +# endif + //...................................................................... +# if SEND_DISH + void sendDISH (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_SHARP + void sendSharpRaw (unsigned long data, int nbits) ; + void sendSharp (unsigned int address, unsigned int command) ; +# endif + //...................................................................... +# if SEND_DENON + void sendDenon (unsigned long data, int nbits) ; +# endif + //...................................................................... +# if SEND_PRONTO + void sendPronto (char* code, bool repeat, bool fallback) ; +# endif +//...................................................................... +# if SEND_LEGO_PF + void sendLegoPowerFunctions (uint16_t data, bool repeat = true) ; +# endif +} ; + +#endif diff --git a/Arduino_Code/Arduino-IRremote/IRremoteInt.h b/Arduino_Code/Arduino-IRremote/IRremoteInt.h new file mode 100644 index 000000000..1c319acbf --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/IRremoteInt.h @@ -0,0 +1,113 @@ +//****************************************************************************** +// IRremote +// Version 2.0.1 June, 2015 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html +// +// Modified by Paul Stoffregen to support other boards and timers +// +// Interrupt code based on NECIRrcv by Joe Knapp +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 +// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ +// +// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +// Whynter A/C ARC-110WD added by Francesco Meschia +//****************************************************************************** + +#ifndef IRremoteint_h +#define IRremoteint_h + +//------------------------------------------------------------------------------ +// Include the right Arduino header +// +#if defined(ARDUINO) && (ARDUINO >= 100) +# include +#else +# if !defined(IRPRONTO) +# include +# endif +#endif + +//------------------------------------------------------------------------------ +// This handles definition and access to global variables +// +#ifdef IR_GLOBAL +# define EXTERN +#else +# define EXTERN extern +#endif + +//------------------------------------------------------------------------------ +// Information for the Interrupt Service Routine +// +#define RAWBUF 101 // Maximum length of raw duration buffer + +typedef + struct { + // The fields are ordered to reduce memory over caused by struct-padding + uint8_t rcvstate; // State Machine state + uint8_t recvpin; // Pin connected to IR data from detector + uint8_t blinkpin; + uint8_t blinkflag; // true -> enable blinking of pin on IR processing + uint8_t rawlen; // counter of entries in rawbuf + unsigned int timer; // State timer, counts 50uS ticks. + unsigned int rawbuf[RAWBUF]; // raw data + uint8_t overflow; // Raw buffer overflow occurred + } +irparams_t; + +// ISR State-Machine : Receiver States +#define STATE_IDLE 2 +#define STATE_MARK 3 +#define STATE_SPACE 4 +#define STATE_STOP 5 +#define STATE_OVERFLOW 6 + +// Allow all parts of the code access to the ISR data +// NB. The data can be changed by the ISR at any time, even mid-function +// Therefore we declare it as "volatile" to stop the compiler/CPU caching it +EXTERN volatile irparams_t irparams; + +//------------------------------------------------------------------------------ +// Defines for setting and clearing register bits +// +#ifndef cbi +# define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif + +#ifndef sbi +# define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +//------------------------------------------------------------------------------ +// Pulse parms are ((X*50)-100) for the Mark and ((X*50)+100) for the Space. +// First MARK is the one after the long gap +// Pulse parameters in uSec +// + +// Due to sensor lag, when received, Marks tend to be 100us too long and +// Spaces tend to be 100us too short +#define MARK_EXCESS 100 + +// Upper and Lower percentage tolerances in measurements +#define TOLERANCE 25 +#define LTOL (1.0 - (TOLERANCE/100.)) +#define UTOL (1.0 + (TOLERANCE/100.)) + +// Minimum gap between IR transmissions +#define _GAP 5000 +#define GAP_TICKS (_GAP/USECPERTICK) + +#define TICKS_LOW(us) ((int)(((us)*LTOL/USECPERTICK))) +#define TICKS_HIGH(us) ((int)(((us)*UTOL/USECPERTICK + 1))) + +//------------------------------------------------------------------------------ +// IR detector output is active low +// +#define MARK 0 +#define SPACE 1 + +// All board specific stuff has been moved to its own file, included here. +#include "boarddefs.h" + +#endif diff --git a/Arduino_Code/Arduino-IRremote/ISSUE_TEMPLATE.md b/Arduino_Code/Arduino-IRremote/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..98358d0e4 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ISSUE_TEMPLATE.md @@ -0,0 +1,25 @@ +**Board:** ARDUINO UNO +**Library Version:** 2.1.0 +**Protocol:** Sony (if any) + +**Code Block:** +```c + +#include + +..... + +``` + +Use [a gist](gist.github.com) if the code exceeds 30 lines + +**checklist:** +- [] I have **read** the README.md file thoroughly +- [] I have searched existing issues to see if there is anything I have missed. +- [] The latest [release](https://github.com/z3t0/Arduino-IRremote/releases/latest) is used +- [] Any code referenced is provided and if over 30 lines a gist is linked INSTEAD of it being pasted in here +- [] The title of the issue is helpful and relevant + +** We will start to close issues that do not follow these guidelines as it doesn't help the contributors who spend time trying to solve issues if the community ignores guidelines!** + +The above is a short template allowing you to make detailed issues! diff --git a/Arduino_Code/Arduino-IRremote/LICENSE.txt b/Arduino_Code/Arduino-IRremote/LICENSE.txt new file mode 100644 index 000000000..77cec6dd1 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/LICENSE.txt @@ -0,0 +1,458 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + diff --git a/Arduino_Code/Arduino-IRremote/README.md b/Arduino_Code/Arduino-IRremote/README.md new file mode 100644 index 000000000..188be38bf --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/README.md @@ -0,0 +1,91 @@ +# IRremote Arduino Library + +[![Build Status](https://travis-ci.org/z3t0/Arduino-IRremote.svg?branch=master)](https://travis-ci.org/z3t0/Arduino-IRremote) + +[![Join the chat at https://gitter.im/z3t0/Arduino-IRremote](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/z3t0/Arduino-IRremote?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +This library enables you to send and receive using infra-red signals on an Arduino. + +Tutorials and more information will be made available on [the official homepage](http://z3t0.github.io/Arduino-IRremote/). + +## Version - 2.2.3 + +## Installation +1. Navigate to the [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. +2. Download the latest release. +3. Extract the zip file +4. Move the "IRremote" folder that has been extracted to your libraries directory. +5. Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors. + + +## FAQ +- IR does not work right when I use Neopixels (aka WS2811/WS2812/WS2812B) +Whether you use the Adafruit Neopixel lib, or FastLED, interrupts get disabled on many lower end CPUs like the basic arduinos. In turn, this stops the IR interrupt handler from running when it needs to. There are some solutions to this on some processors, [see this page from Marc MERLIN](http://marc.merlins.org/perso/arduino/post_2017-04-03_Arduino-328P-Uno-Teensy3_1-ESP8266-ESP32-IR-and-Neopixels.html) + + +## Supported Boards +- Arduino Uno / Mega / Leonardo / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano etc. +- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Credits: @PaulStoffregen (Teensy Team) +- Sanguino +- ATmega8, 48, 88, 168, 328 +- ATmega8535, 16, 32, 164, 324, 644, 1284, +- ATmega64, 128 +- ATtiny 84 / 85 +- ESP32 (receive only) +- ESP8266 is supported in a fork based on an old codebase that isn't as recent, but it works reasonably well given that perfectly timed sub millisecond interrupts are different on that chip. See https://github.com/markszabo/IRremoteESP8266 +- Sparkfun Pro Micro + +We are open to suggestions for adding support to new boards, however we highly recommend you contact your supplier first and ask them to provide support from their side. + +### Hardware specifications + +| Board/CPU | Send Pin | Timers | +|--------------------------------------------------------------------------|---------------------|-------------------| +| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** | +| [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** | +| [ATmega8](https://github.com/MCUdude/MiniCore) | **9** | **1** | +| Atmega32u4 | 5, 9, **13** | 1, 3, **4** | +| [ATmega48, ATmega88, ATmega168, ATmega328](https://github.com/MCUdude/MiniCore) | **3**, 9 | 1, **2** | +| [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 | +| [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** | +| [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** | +| [ATmega64, ATmega128](https://github.com/MCUdude/MegaCore) | **13** | **1** | +| ATmega1280, ATmega2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 | +| [ESP32](http://esp32.net/) | N/A (not supported) | **1** | +| [Sparkfun Pro Micro](https://www.sparkfun.com/products/12640) | 9, **5**, 5 | 1, **3**, 4_HS | +| [Teensy 1.0](https://www.pjrc.com/teensy/) | **17** | **1** | +| [Teensy 2.0](https://www.pjrc.com/teensy/) | 9, **10**, 14 | 1, 3, **4_HS** | +| [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/) | **1**, 16, 25 | 1, **2**, 3 | +| [Teensy 3.0 / 3.1](https://www.pjrc.com/teensy/) | **5** | **CMT** | +| [Teensy-LC](https://www.pjrc.com/teensy/) | **16** | **TPM1** | + + +### Experimental patches +The following are strictly community supported patches that have yet to make it into mainstream. If you have issues feel free to ask here. If it works well then let us know! + +[Arduino 101](https://github.com/z3t0/Arduino-IRremote/pull/481#issuecomment-311243146) + +The table above lists the currently supported timers and corresponding send pins, many of these can have additional pins opened up and we are open to requests if a need arises for other pins. + +## Usage +- TODO (Check examples for now) + +## Contributing +If you want to contribute to this project: +- Report bugs and errors +- Ask for enhancements +- Create issues and pull requests +- Tell other people about this library +- Contribute new protocols + +Check [here](Contributing.md) for some guidelines. + +## Contact +Email: zetoslab@gmail.com +Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. + +## Contributors +Check [here](Contributors.md) + +## Copyright +Copyright 2009-2012 Ken Shirriff diff --git a/Arduino_Code/Arduino-IRremote/_gitignore b/Arduino_Code/Arduino-IRremote/_gitignore new file mode 100644 index 000000000..e24b84cda --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/_gitignore @@ -0,0 +1,3 @@ +*.un~ +*.sublime-project +*.sublime-workspace \ No newline at end of file diff --git a/Arduino_Code/Arduino-IRremote/_travis.yml b/Arduino_Code/Arduino-IRremote/_travis.yml new file mode 100644 index 000000000..543a0a74b --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/_travis.yml @@ -0,0 +1,30 @@ +language: python +python: + - "2.7" + +# Cache PlatformIO packages using Travis CI container-based infrastructure +sudo: false +cache: + directories: + - "~/.platformio" + +env: + - PLATFORMIO_CI_SRC=examples/AiwaRCT501SendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_AIWA_RC_T501" + - PLATFORMIO_CI_SRC=examples/IRrecord PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" + - PLATFORMIO_CI_SRC=examples/IRrecvDemo + - PLATFORMIO_CI_SRC=examples/IRrecvDump + - PLATFORMIO_CI_SRC=examples/IRrecvDumpV2 + - PLATFORMIO_CI_SRC=examples/IRrelay + - PLATFORMIO_CI_SRC=examples/IRsendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_SONY" + - PLATFORMIO_CI_SRC=examples/IRtest PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" + - PLATFORMIO_CI_SRC=examples/IRtest2 PLATFORMIO_BUILD_FLAGS="-DSEND_NEC -DSEND_SONY -DSEND_RC5 -DSEND_RC6" + - PLATFORMIO_CI_SRC=examples/JVCPanasonicSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_JVC -DSEND_PANASONIC" + - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsSendDemo PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" + - PLATFORMIO_CI_SRC=examples/LegoPowerFunctionsTests PLATFORMIO_BUILD_FLAGS="-DSEND_LEGO_PF" + - PLATFORMIO_CI_SRC=examples/IRremoteInfo + +install: + - pip install -U platformio + +script: + - platformio ci --lib="." --board=uno --board=leonardo --board=pro16MHzatmega168 --board=btatmega328 diff --git a/Arduino_Code/Arduino-IRremote/arduino-irremote.sublime-workspace b/Arduino_Code/Arduino-IRremote/arduino-irremote.sublime-workspace new file mode 100644 index 000000000..f536803d0 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/arduino-irremote.sublime-workspace @@ -0,0 +1,240 @@ +{ + "auto_complete": + { + "selected_items": + [ + [ + "vb", + "vboMatrix" + ] + ] + }, + "buffers": + [ + ], + "build_system": "", + "build_system_choices": + [ + ], + "build_varint": "", + "command_palette": + { + "height": 275.0, + "last_filter": "blame", + "selected_items": + [ + [ + "blame", + "Git: Blame" + ], + [ + "install", + "Package Control: Install Package" + ], + [ + "diff", + "Git: Diff Current File" + ], + [ + "js", + "Set Syntax: JavaScript" + ], + [ + "i", + "Package Control: Install Package" + ], + [ + "instal", + "Package Control: Install Package" + ] + ], + "width": 510.0 + }, + "console": + { + "height": 126.0, + "history": + [ + "import urllib.request,os,hashlib; h = '2915d1851351e5ee549c20394736b442' + '8bc59f460fa1548d1514676163dafc88'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)" + ] + }, + "distraction_free": + { + "menu_visible": true, + "show_minimap": false, + "show_open_files": false, + "show_tabs": false, + "side_bar_visible": false, + "status_bar_visible": false + }, + "expanded_folders": + [ + "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote" + ], + "file_history": + [ + "/C/Users/Rafi Khan/Documents/Arduino/libraries/Arduino-IRremote/changelog.md", + "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/arduino-irremote.sublime-project", + "/C/Users/Rafi Khan/Documents/Development/Arduino-IRremote/.gitignore", + "/C/Users/Rafi Khan/Documents/Development/magic/README.md", + "/C/Users/Rafi Khan/Documents/Development/magic/shader.frag", + "/C/Users/Rafi Khan/Documents/Development/magic/package.json", + "/C/Users/Rafi Khan/Documents/Development/magic/block.js", + "/C/Users/Rafi Khan/Documents/Development/magic/chunker.js", + "/C/Users/Rafi Khan/Documents/Development/magic/index.js", + "/C/Users/Rafi Khan/Documents/Development/magic/blocks", + "/C/Users/Rafi Khan/AppData/Roaming/Sublime Text 3/Packages/User/Preferences.sublime-settings", + "/C/Users/Rafi Khan/Documents/Development/magic/shader.vert", + "/C/Users/Rafi Khan/Documents/Development/magic/magic.sublime-project", + "/C/Users/Rafi Khan/Documents/Development/magic/node_modules/browserify/node_modules/syntax-error/node_modules/acorn/.tern-project", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/supermarket.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/takingavacation.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/TipCalculator.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/battleship.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/exam.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/pyglatin.py", + "/C/Users/Rafi Khan/OneDrive/Documents/School-RafiKhan/Grade 11/CS30/Python/student.py" + ], + "find": + { + "height": 28.0 + }, + "find_in_files": + { + "height": 0.0, + "where_history": + [ + ] + }, + "find_state": + { + "case_sensitive": false, + "find_history": + [ + "i", + "Direction", + ";", + ";\n", + "north", + "cubeMatrix", + ")\n", + "vec3.set", + "f", + ";", + "();\n", + "render", + "this", + "y" + ], + "highlight": true, + "in_selection": false, + "preserve_case": false, + "regex": false, + "replace_history": + [ + ], + "reverse": false, + "show_context": true, + "use_buffer2": true, + "whole_word": false, + "wrap": true + }, + "groups": + [ + { + "sheets": + [ + ] + } + ], + "incremental_find": + { + "height": 28.0 + }, + "input": + { + "height": 66.0 + }, + "layout": + { + "cells": + [ + [ + 0, + 0, + 1, + 1 + ] + ], + "cols": + [ + 0.0, + 1.0 + ], + "rows": + [ + 0.0, + 1.0 + ] + }, + "menu_visible": true, + "output.find_results": + { + "height": 0.0 + }, + "pinned_build_system": "", + "project": "arduino-irremote.sublime-project", + "replace": + { + "height": 52.0 + }, + "save_all_on_build": true, + "select_file": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "json", + "package.json" + ], + [ + "inde", + "index.js" + ] + ], + "width": 0.0 + }, + "select_project": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_symbol": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "selected_group": 0, + "settings": + { + }, + "show_minimap": true, + "show_open_files": false, + "show_tabs": true, + "side_bar_visible": true, + "side_bar_width": 150.0, + "status_bar_visible": true, + "template_settings": + { + } +} diff --git a/Arduino_Code/Arduino-IRremote/boarddefs.h b/Arduino_Code/Arduino-IRremote/boarddefs.h new file mode 100644 index 000000000..a61dd856f --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/boarddefs.h @@ -0,0 +1,595 @@ +//****************************************************************************** +// IRremote +// Version 2.0.1 June, 2015 +// Copyright 2009 Ken Shirriff +// For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html + +// This file contains all board specific information. It was previously contained within +// IRremoteInt.h + +// Modified by Paul Stoffregen to support other boards and timers +// +// Interrupt code based on NECIRrcv by Joe Knapp +// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 +// Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ +// +// JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +// Whynter A/C ARC-110WD added by Francesco Meschia + +// Sparkfun Pro Micro support by Alastair McCormack +//****************************************************************************** + +#ifndef boarddefs_h +#define boarddefs_h + +//------------------------------------------------------------------------------ +// Defines for blinking the LED +// + +#if defined(CORE_LED0_PIN) +# define BLINKLED CORE_LED0_PIN +# define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH)) +# define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW)) + +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B10000000) +# define BLINKLED_OFF() (PORTB &= B01111111) + +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +# define BLINKLED 0 +# define BLINKLED_ON() (PORTD |= B00000001) +# define BLINKLED_OFF() (PORTD &= B11111110) + +// No system LED on ESP32, disable blinking +#elif defined(ESP32) +# define BLINKLED 255 +# define BLINKLED_ON() 1 +# define BLINKLED_OFF() 1 +#else +# define BLINKLED 13 +# define BLINKLED_ON() (PORTB |= B00100000) +# define BLINKLED_OFF() (PORTB &= B11011111) +#endif + +//------------------------------------------------------------------------------ +// CPU Frequency +// +#ifdef F_CPU +# define SYSCLOCK F_CPU // main Arduino clock +#else +# define SYSCLOCK 16000000 // main Arduino clock +#endif + +// microseconds per clock interrupt tick +#define USECPERTICK 50 + +//------------------------------------------------------------------------------ +// Define which timer to use +// +// Uncomment the timer you wish to use on your board. +// If you are using another library which uses timer2, you have options to +// switch IRremote to use a different timer. +// + +// Sparkfun Pro Micro +#if defined(ARDUINO_AVR_PROMICRO) + //#define IR_USE_TIMER1 // tx = pin 9 + #define IR_USE_TIMER3 // tx = pin 5 + //#define IR_USE_TIMER4_HS // tx = pin 5 + +// Arduino Mega +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + //#define IR_USE_TIMER1 // tx = pin 11 + #define IR_USE_TIMER2 // tx = pin 9 + //#define IR_USE_TIMER3 // tx = pin 5 + //#define IR_USE_TIMER4 // tx = pin 6 + //#define IR_USE_TIMER5 // tx = pin 46 + +// Teensy 1.0 +#elif defined(__AVR_AT90USB162__) + #define IR_USE_TIMER1 // tx = pin 17 + +// Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + //#define IR_USE_TIMER1 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 9 + #define IR_USE_TIMER4_HS // tx = pin 10 + +// Teensy 3.0 / Teensy 3.1 +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) + #define IR_USE_TIMER_CMT // tx = pin 5 + +// Teensy-LC +#elif defined(__MKL26Z64__) + #define IR_USE_TIMER_TPM1 // tx = pin 16 + +// Teensy++ 1.0 & 2.0 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + //#define IR_USE_TIMER1 // tx = pin 25 + #define IR_USE_TIMER2 // tx = pin 1 + //#define IR_USE_TIMER3 // tx = pin 16 + +// MightyCore - ATmega1284 +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 6 + +// MightyCore - ATmega164, ATmega324, ATmega644 +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + +//MegaCore - ATmega64, ATmega128 +#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) + #define IR_USE_TIMER1 // tx = pin 13 + +// MightyCore - ATmega8535, ATmega16, ATmega32 +#elif defined(__AVR_ATmega8535__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) + #define IR_USE_TIMER1 // tx = pin 13 + +// Atmega8 +#elif defined(__AVR_ATmega8__) + #define IR_USE_TIMER1 // tx = pin 9 + +// ATtiny84 +#elif defined(__AVR_ATtiny84__) + #define IR_USE_TIMER1 // tx = pin 6 + +//ATtiny85 +#elif defined(__AVR_ATtiny85__) + #define IR_USE_TIMER_TINY0 // tx = pin 1 + +#elif defined(ESP32) + #define IR_TIMER_USE_ESP32 +#else +// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc +// ATmega48, ATmega88, ATmega168, ATmega328 + //#define IR_USE_TIMER1 // tx = pin 9 + #define IR_USE_TIMER2 // tx = pin 3 + +#endif + +//------------------------------------------------------------------------------ +// Defines for Timer + +//--------------------------------------------------------- +// Timer2 (8 bits) +// +#if defined(IR_USE_TIMER2) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) +#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) +#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) +#define TIMER_DISABLE_INTR (TIMSK2 = 0) +#define TIMER_INTR_NAME TIMER2_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR2A = _BV(WGM20); \ + TCCR2B = _BV(WGM22) | _BV(CS20); \ + OCR2A = pwmval; \ + OCR2B = pwmval / 3; \ +}) + +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) + +//----------------- +#if (TIMER_COUNT_TOP < 256) +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS20); \ + OCR2A = TIMER_COUNT_TOP; \ + TCNT2 = 0; \ + }) +#else +# define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS21); \ + OCR2A = TIMER_COUNT_TOP / 8; \ + TCNT2 = 0; \ + }) +#endif + +//----------------- +#if defined(CORE_OC2B_PIN) +# define TIMER_PWM_PIN CORE_OC2B_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 9 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) +# define TIMER_PWM_PIN 14 // MightyCore +#else +# define TIMER_PWM_PIN 3 // Arduino Duemilanove, Diecimila, LilyPad, etc +#endif // ATmega48, ATmega88, ATmega168, ATmega328 + +//--------------------------------------------------------- +// Timer1 (16 bits) +// +#elif defined(IR_USE_TIMER1) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) +#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) + +//----------------- +#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega8535__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK &= ~_BV(OCIE1A)) +#else +# define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) +# define TIMER_DISABLE_INTR (TIMSK1 = 0) +#endif + +//----------------- +#define TIMER_INTR_NAME TIMER1_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR1A = _BV(WGM11); \ + TCCR1B = _BV(WGM13) | _BV(CS10); \ + ICR1 = pwmval; \ + OCR1A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR1A = 0; \ + TCCR1B = _BV(WGM12) | _BV(CS10); \ + OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT1 = 0; \ +}) + +//----------------- +#if defined(CORE_OC1A_PIN) +# define TIMER_PWM_PIN CORE_OC1A_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 11 // Arduino Mega +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \ +|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \ +|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \ +|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \ +|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \ +|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \ +|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) +# define TIMER_PWM_PIN 13 // MightyCore, MegaCore +#elif defined(__AVR_ATtiny84__) +# define TIMER_PWM_PIN 6 +#else +# define TIMER_PWM_PIN 9 // Arduino Duemilanove, Diecimila, LilyPad, Sparkfun Pro Micro etc +#endif // ATmega48, ATmega88, ATmega168, ATmega328 + +//--------------------------------------------------------- +// Timer3 (16 bits) +// +#elif defined(IR_USE_TIMER3) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) +#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) +#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) +#define TIMER_DISABLE_INTR (TIMSK3 = 0) +#define TIMER_INTR_NAME TIMER3_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR3A = _BV(WGM31); \ + TCCR3B = _BV(WGM33) | _BV(CS30); \ + ICR3 = pwmval; \ + OCR3A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR3A = 0; \ + TCCR3B = _BV(WGM32) | _BV(CS30); \ + OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT3 = 0; \ +}) + +//----------------- +#if defined(CORE_OC3A_PIN) +# define TIMER_PWM_PIN CORE_OC3A_PIN // Teensy +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ARDUINO_AVR_PROMICRO) +# define TIMER_PWM_PIN 5 // Arduino Mega, Sparkfun Pro Micro +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) +# define TIMER_PWM_PIN 6 // MightyCore +#else +# error "Please add OC3A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer4 (10 bits, high speed option) +// +#elif defined(IR_USE_TIMER4_HS) + +#define TIMER_RESET + +#if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro + #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A0)) // Use complimentary O̅C̅4̅A̅ output on pin 5 + #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A0))) // (Pro Micro does not map PC7 (32/ICP3/CLK0/OC4A) + // of ATmega32U4 ) +#else + #define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) + #define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#endif + +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_OVF_vect + + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = (1<> 8; \ + OCR4C = pwmval; \ + TC4H = (pwmval / 3) >> 8; \ + OCR4A = (pwmval / 3) & 255; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(CS40); \ + TCCR4C = 0; \ + TCCR4D = 0; \ + TCCR4E = 0; \ + TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ + OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ + TC4H = 0; \ + TCNT4 = 0; \ +}) + +//----------------- +#if defined(CORE_OC4A_PIN) +# define TIMER_PWM_PIN CORE_OC4A_PIN // Teensy +#elif defined(ARDUINO_AVR_PROMICRO) +# define TIMER_PWM_PIN 5 // Sparkfun Pro Micro +#elif defined(__AVR_ATmega32U4__) +# define TIMER_PWM_PIN 13 // Leonardo +#else +# error "Please add OC4A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer4 (16 bits) +// +#elif defined(IR_USE_TIMER4) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = _BV(WGM41); \ + TCCR4B = _BV(WGM43) | _BV(CS40); \ + ICR4 = pwmval; \ + OCR4A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(WGM42) | _BV(CS40); \ + OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT4 = 0; \ +}) + +//----------------- +#if defined(CORE_OC4A_PIN) +# define TIMER_PWM_PIN CORE_OC4A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 6 // Arduino Mega +#else +# error "Please add OC4A pin number here\n" +#endif + +//--------------------------------------------------------- +// Timer5 (16 bits) +// +#elif defined(IR_USE_TIMER5) + +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) +#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) +#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) +#define TIMER_DISABLE_INTR (TIMSK5 = 0) +#define TIMER_INTR_NAME TIMER5_COMPA_vect + +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR5A = _BV(WGM51); \ + TCCR5B = _BV(WGM53) | _BV(CS50); \ + ICR5 = pwmval; \ + OCR5A = pwmval / 3; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR5A = 0; \ + TCCR5B = _BV(WGM52) | _BV(CS50); \ + OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT5 = 0; \ +}) + +//----------------- +#if defined(CORE_OC5A_PIN) +# define TIMER_PWM_PIN CORE_OC5A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +# define TIMER_PWM_PIN 46 // Arduino Mega +#else +# error "Please add OC5A pin number here\n" +#endif + +//--------------------------------------------------------- +// Special carrier modulator timer +// +#elif defined(IR_USE_TIMER_CMT) + +#define TIMER_RESET ({ \ + uint8_t tmp __attribute__((unused)) = CMT_MSC; \ + CMT_CMD2 = 30; \ +}) + +#define TIMER_ENABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(2) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_DISABLE_PWM do { \ + CORE_PIN5_CONFIG = PORT_PCR_MUX(1) | PORT_PCR_DSE | PORT_PCR_SRE; \ +} while(0) + +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) +#define TIMER_INTR_NAME cmt_isr + +//----------------- +#ifdef ISR +# undef ISR +#endif +#define ISR(f) void f(void) + +//----------------- +#define CMT_PPS_DIV ((F_BUS + 7999999) / 8000000) +#if F_BUS < 8000000 +#error IRremote requires at least 8 MHz on Teensy 3.x +#endif + +//----------------- +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = ((F_BUS / CMT_PPS_DIV / 3000) + ((val)/2)) / (val); \ + CMT_CGL1 = ((F_BUS / CMT_PPS_DIV / 1500) + ((val)/2)) / (val); \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 0; \ + CMT_OC = 0x60; \ + CMT_MSC = 0x01; \ +}) + +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + CMT_PPS = CMT_PPS_DIV - 1; \ + CMT_CGH1 = 1; \ + CMT_CGL1 = 1; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = (F_BUS / 160000 + CMT_PPS_DIV / 2) / CMT_PPS_DIV - 31; \ + CMT_OC = 0; \ + CMT_MSC = 0x03; \ +}) + +#define TIMER_PWM_PIN 5 + +// defines for TPM1 timer on Teensy-LC +#elif defined(IR_USE_TIMER_TPM1) +#define TIMER_RESET FTM1_SC |= FTM_SC_TOF; +#define TIMER_ENABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_DISABLE_PWM CORE_PIN16_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_FTM1) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_FTM1) +#define TIMER_INTR_NAME ftm1_isr +#ifdef ISR +#undef ISR +#endif +#define ISR(f) void f(void) +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/2000) / val - 1; \ + FTM1_C0V = (F_PLL/6000) / val - 1; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0); \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC6 |= SIM_SCGC6_TPM1; \ + FTM1_SC = 0; \ + FTM1_CNT = 0; \ + FTM1_MOD = (F_PLL/40000) - 1; \ + FTM1_C0V = 0; \ + FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE; \ +}) +#define TIMER_PWM_PIN 16 + +// defines for timer_tiny0 (8 bits) +#elif defined(IR_USE_TIMER_TINY0) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR0A |= _BV(COM0B1)) +#define TIMER_DISABLE_PWM (TCCR0A &= ~(_BV(COM0B1))) +#define TIMER_ENABLE_INTR (TIMSK |= _BV(OCIE0A)) +#define TIMER_DISABLE_INTR (TIMSK &= ~(_BV(OCIE0A))) +#define TIMER_INTR_NAME TIMER0_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR0A = _BV(WGM00); \ + TCCR0B = _BV(WGM02) | _BV(CS00); \ + OCR0A = pwmval; \ + OCR0B = pwmval / 3; \ +}) +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) +#if (TIMER_COUNT_TOP < 256) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS00); \ + OCR0A = TIMER_COUNT_TOP; \ + TCNT0 = 0; \ +}) +#else +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR0A = _BV(WGM01); \ + TCCR0B = _BV(CS01); \ + OCR0A = TIMER_COUNT_TOP / 8; \ + TCNT0 = 0; \ +}) +#endif + +#define TIMER_PWM_PIN 1 /* ATtiny85 */ + +//--------------------------------------------------------- +// ESP32 (ESP8266 should likely be added here too) +// + +// ESP32 has it own timer API and does not use these macros, but to avoid ifdef'ing +// them out in the common code, they are defined to no-op. This allows the code to compile +// (which it wouldn't otherwise) but irsend will not work until ESP32 specific code is written +// for that -- merlin +// As a warning, sending timing specific code from an ESP32 can be challenging if you need 100% +// reliability because the arduino code may be interrupted and cause your sent waveform to be the +// wrong length. This is specifically an issue for neopixels which require 800Khz resolution. +// IR may just work as is with the common code since it's lower frequency, but if not, the other +// way to do this on ESP32 is using the RMT built in driver like in this incomplete library below +// https://github.com/ExploreEmbedded/ESP32_RMT +#elif defined(IR_TIMER_USE_ESP32) +#define TIMER_RESET +#define TIMER_ENABLE_PWM +#define TIMER_DISABLE_PWM Serial.println("IRsend not implemented for ESP32 yet"); +#define TIMER_ENABLE_INTR +#define TIMER_DISABLE_INTR +#define TIMER_INTR_NAME + +//--------------------------------------------------------- +// Unknown Timer +// +#else +# error "Internal code configuration error, no known IR_USE_TIMER# defined\n" +#endif + +#endif // ! boarddefs_h diff --git a/Arduino_Code/Arduino-IRremote/changelog.md b/Arduino_Code/Arduino-IRremote/changelog.md new file mode 100644 index 000000000..81339f2e6 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/changelog.md @@ -0,0 +1,78 @@ +## 2.3.3 - 2017/03/31 +- Added ESP32 IR receive support [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/425) + +## 2.2.3 - 2017/03/27 +- Fix calculation of pause length in LEGO PF protocol [PR #427](https://github.com/z3t0/Arduino-IRremote/pull/427) + +## 2.2.2 - 2017/01/20 +- Fixed naming bug [PR #398](https://github.com/z3t0/Arduino-IRremote/pull/398) + +## 2.2.1 - 2016/07/27 +- Added tests for Lego Power Functions Protocol [PR #336](https://github.com/z3t0/Arduino-IRremote/pull/336) + +## 2.2.0 - 2016/06/28 +- Added support for ATmega8535 +- Added support for ATmega16 +- Added support for ATmega32 +- Added support for ATmega164 +- Added support for ATmega324 +- Added support for ATmega644 +- Added support for ATmega1284 +- Added support for ATmega64 +- Added support for ATmega128 + +[PR](https://github.com/z3t0/Arduino-IRremote/pull/324) + +## 2.1.1 - 2016/05/04 +- Added Lego Power Functions Protocol [PR #309](https://github.com/z3t0/Arduino-IRremote/pull/309) + +## 2.1.0 - 2016/02/20 +- Improved Debugging [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) +- Display TIME instead of TICKS [PR #258](https://github.com/z3t0/Arduino-IRremote/pull/258) + +## 2.0.4 - 2016/02/20 +- Add Panasonic and JVC to IRrecord example [PR](https://github.com/z3t0/Arduino-IRremote/pull/54) + +## 2.0.3 - 2016/02/20 +- Change IRSend Raw parameter to const [PR](https://github.com/z3t0/Arduino-IRremote/pull/227) + +## 2.0.2 - 2015/12/02 +- Added IRremoteInfo Sketch - [PR](https://github.com/z3t0/Arduino-IRremote/pull/241) +- Enforcing changelog.md + +## 2.0.1 - 2015/07/26 - [Release](https://github.com/shirriff/Arduino-IRremote/releases/tag/BETA) +### Changes +- Updated README +- Updated Contributors +- Fixed #110 Mess +- Created Gitter Room +- Added Gitter Badge +- Standardised Code Base +- Clean Debug Output +- Optimized Send Loops +- Modularized Design +- Optimized and Updated Examples +- Improved Documentation +- Fixed and Improved many coding errors +- Fixed Aiwa RC-T501 Decoding +- Fixed Interrupt on ATmega8 +- Switched to Stable Release of @PlatformIO + +### Additions +- Added Aiwa RC-T501 Protocol +- Added Denon Protocol +- Added Pronto Support +- Added Library Properties +- Added Template For New Protocols +- Added this changelog +- Added Teensy LC Support +- Added ATtiny84 Support +- Added ATtiny85 Support +- Added isIdle method + +### Deletions +- Removed (Fixed) #110 +- Broke Teensy 3 / 3.1 Support + +### Not Working +- Teensy 3 / 3.1 Support is in Development diff --git a/Arduino_Code/Arduino-IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino b/Arduino_Code/Arduino-IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino new file mode 100644 index 000000000..5a9862bf3 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/AiwaRCT501SendDemo/AiwaRCT501SendDemo.ino @@ -0,0 +1,26 @@ +/* + * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend + * An IR LED must be connected to Arduino PWM pin 3. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + */ + +#include "IRremote.h" + +#define POWER 0x7F80 +#define AIWA_RC_T501 + +IRsend irsend; + +void setup() { + Serial.begin(9600); + Serial.println("Arduino Ready"); +} + +void loop() { + if (Serial.read() != -1) { + irsend.sendAiwaRCT501(POWER); + delay(60); // Optional + } +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRrecord/IRrecord.ino b/Arduino_Code/Arduino-IRremote/examples/IRrecord/IRrecord.ino new file mode 100644 index 000000000..a121e590d --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRrecord/IRrecord.ino @@ -0,0 +1,183 @@ +/* + * IRrecord: record and play back IR signals as a minimal + * An IR detector/demodulator must be connected to the input RECV_PIN. + * An IR LED must be connected to the output PWM pin 3. + * A button must be connected to the input BUTTON_PIN; this is the + * send button. + * A visible LED can be connected to STATUS_PIN to provide status. + * + * The logic is: + * If the button is pressed, send the IR code. + * If an IR code is received, record it. + * + * Version 0.11 September, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + */ + +#include + +int RECV_PIN = 11; +int BUTTON_PIN = 12; +int STATUS_PIN = 13; + +IRrecv irrecv(RECV_PIN); +IRsend irsend; + +decode_results results; + +void setup() +{ + Serial.begin(9600); + irrecv.enableIRIn(); // Start the receiver + pinMode(BUTTON_PIN, INPUT); + pinMode(STATUS_PIN, OUTPUT); +} + +// Storage for the recorded code +int codeType = -1; // The type of code +unsigned long codeValue; // The code value if not raw +unsigned int rawCodes[RAWBUF]; // The durations if raw +int codeLen; // The length of the code +int toggle = 0; // The RC5/6 toggle state + +// Stores the code for later playback +// Most of this code is just logging +void storeCode(decode_results *results) { + codeType = results->decode_type; + //int count = results->rawlen; + if (codeType == UNKNOWN) { + Serial.println("Received unknown code, saving as raw"); + codeLen = results->rawlen - 1; + // To store raw codes: + // Drop first value (gap) + // Convert from ticks to microseconds + // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion + for (int i = 1; i <= codeLen; i++) { + if (i % 2) { + // Mark + rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS; + Serial.print(" m"); + } + else { + // Space + rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS; + Serial.print(" s"); + } + Serial.print(rawCodes[i - 1], DEC); + } + Serial.println(""); + } + else { + if (codeType == NEC) { + Serial.print("Received NEC: "); + if (results->value == REPEAT) { + // Don't record a NEC repeat value as that's useless. + Serial.println("repeat; ignoring."); + return; + } + } + else if (codeType == SONY) { + Serial.print("Received SONY: "); + } + else if (codeType == PANASONIC) { + Serial.print("Received PANASONIC: "); + } + else if (codeType == JVC) { + Serial.print("Received JVC: "); + } + else if (codeType == RC5) { + Serial.print("Received RC5: "); + } + else if (codeType == RC6) { + Serial.print("Received RC6: "); + } + else { + Serial.print("Unexpected codeType "); + Serial.print(codeType, DEC); + Serial.println(""); + } + Serial.println(results->value, HEX); + codeValue = results->value; + codeLen = results->bits; + } +} + +void sendCode(int repeat) { + if (codeType == NEC) { + if (repeat) { + irsend.sendNEC(REPEAT, codeLen); + Serial.println("Sent NEC repeat"); + } + else { + irsend.sendNEC(codeValue, codeLen); + Serial.print("Sent NEC "); + Serial.println(codeValue, HEX); + } + } + else if (codeType == SONY) { + irsend.sendSony(codeValue, codeLen); + Serial.print("Sent Sony "); + Serial.println(codeValue, HEX); + } + else if (codeType == PANASONIC) { + irsend.sendPanasonic(codeValue, codeLen); + Serial.print("Sent Panasonic"); + Serial.println(codeValue, HEX); + } + else if (codeType == JVC) { + irsend.sendJVC(codeValue, codeLen, false); + Serial.print("Sent JVC"); + Serial.println(codeValue, HEX); + } + else if (codeType == RC5 || codeType == RC6) { + if (!repeat) { + // Flip the toggle bit for a new button press + toggle = 1 - toggle; + } + // Put the toggle bit into the code to send + codeValue = codeValue & ~(1 << (codeLen - 1)); + codeValue = codeValue | (toggle << (codeLen - 1)); + if (codeType == RC5) { + Serial.print("Sent RC5 "); + Serial.println(codeValue, HEX); + irsend.sendRC5(codeValue, codeLen); + } + else { + irsend.sendRC6(codeValue, codeLen); + Serial.print("Sent RC6 "); + Serial.println(codeValue, HEX); + } + } + else if (codeType == UNKNOWN /* i.e. raw */) { + // Assume 38 KHz + irsend.sendRaw(rawCodes, codeLen, 38); + Serial.println("Sent raw"); + } +} + +int lastButtonState; + +void loop() { + // If button pressed, send the code. + int buttonState = digitalRead(BUTTON_PIN); + if (lastButtonState == HIGH && buttonState == LOW) { + Serial.println("Released"); + irrecv.enableIRIn(); // Re-enable receiver + } + + if (buttonState) { + Serial.println("Pressed, sending"); + digitalWrite(STATUS_PIN, HIGH); + sendCode(lastButtonState == buttonState); + digitalWrite(STATUS_PIN, LOW); + delay(50); // Wait a bit between retransmissions + } + else if (irrecv.decode(&results)) { + digitalWrite(STATUS_PIN, HIGH); + storeCode(&results); + irrecv.resume(); // resume receiver + digitalWrite(STATUS_PIN, LOW); + } + lastButtonState = buttonState; +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRrecvDemo/IRrecvDemo.ino b/Arduino_Code/Arduino-IRremote/examples/IRrecvDemo/IRrecvDemo.ino new file mode 100644 index 000000000..3e2d280eb --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRrecvDemo/IRrecvDemo.ino @@ -0,0 +1,33 @@ +/* + * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv + * An IR detector/demodulator must be connected to the input RECV_PIN. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + */ + +#include + +int RECV_PIN = 11; + +IRrecv irrecv(RECV_PIN); + +decode_results results; + +void setup() +{ + Serial.begin(9600); + // In case the interrupt driver crashes on setup, give a clue + // to the user what's going on. + Serial.println("Enabling IRin"); + irrecv.enableIRIn(); // Start the receiver + Serial.println("Enabled IRin"); +} + +void loop() { + if (irrecv.decode(&results)) { + Serial.println(results.value, HEX); + irrecv.resume(); // Receive the next value + } + delay(100); +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRrecvDump/IRrecvDump.ino b/Arduino_Code/Arduino-IRremote/examples/IRrecvDump/IRrecvDump.ino new file mode 100644 index 000000000..fa25cd8ea --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRrecvDump/IRrecvDump.ino @@ -0,0 +1,95 @@ +/* + * IRremote: IRrecvDump - dump details of IR codes with IRrecv + * An IR detector/demodulator must be connected to the input RECV_PIN. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) + * LG added by Darryl Smith (based on the JVC protocol) + */ + +#include + +/* +* Default is Arduino pin D11. +* You can change this to another available Arduino Pin. +* Your IR receiver should be connected to the pin defined here +*/ +int RECV_PIN = 11; + +IRrecv irrecv(RECV_PIN); + +decode_results results; + +void setup() +{ + Serial.begin(9600); + irrecv.enableIRIn(); // Start the receiver +} + + +void dump(decode_results *results) { + // Dumps out the decode_results structure. + // Call this after IRrecv::decode() + int count = results->rawlen; + if (results->decode_type == UNKNOWN) { + Serial.print("Unknown encoding: "); + } + else if (results->decode_type == NEC) { + Serial.print("Decoded NEC: "); + + } + else if (results->decode_type == SONY) { + Serial.print("Decoded SONY: "); + } + else if (results->decode_type == RC5) { + Serial.print("Decoded RC5: "); + } + else if (results->decode_type == RC6) { + Serial.print("Decoded RC6: "); + } + else if (results->decode_type == PANASONIC) { + Serial.print("Decoded PANASONIC - Address: "); + Serial.print(results->address, HEX); + Serial.print(" Value: "); + } + else if (results->decode_type == LG) { + Serial.print("Decoded LG: "); + } + else if (results->decode_type == JVC) { + Serial.print("Decoded JVC: "); + } + else if (results->decode_type == AIWA_RC_T501) { + Serial.print("Decoded AIWA RC T501: "); + } + else if (results->decode_type == WHYNTER) { + Serial.print("Decoded Whynter: "); + } + Serial.print(results->value, HEX); + Serial.print(" ("); + Serial.print(results->bits, DEC); + Serial.println(" bits)"); + Serial.print("Raw ("); + Serial.print(count, DEC); + Serial.print("): "); + + for (int i = 1; i < count; i++) { + if (i & 1) { + Serial.print(results->rawbuf[i]*USECPERTICK, DEC); + } + else { + Serial.write('-'); + Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC); + } + Serial.print(" "); + } + Serial.println(); +} + +void loop() { + if (irrecv.decode(&results)) { + Serial.println(results.value, HEX); + dump(&results); + irrecv.resume(); // Receive the next value + } +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/Arduino_Code/Arduino-IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino new file mode 100644 index 000000000..725612735 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRrecvDumpV2/IRrecvDumpV2.ino @@ -0,0 +1,177 @@ +//------------------------------------------------------------------------------ +// Include the IRremote library header +// +#include + +//------------------------------------------------------------------------------ +// Tell IRremote which Arduino pin is connected to the IR Receiver (TSOP4838) +// +int recvPin = 11; +IRrecv irrecv(recvPin); + +//+============================================================================= +// Configure the Arduino +// +void setup ( ) +{ + Serial.begin(9600); // Status message will be sent to PC at 9600 baud + irrecv.enableIRIn(); // Start the receiver +} + +//+============================================================================= +// Display IR code +// +void ircode (decode_results *results) +{ + // Panasonic has an Address + if (results->decode_type == PANASONIC) { + Serial.print(results->address, HEX); + Serial.print(":"); + } + + // Print Code + Serial.print(results->value, HEX); +} + +//+============================================================================= +// Display encoding type +// +void encoding (decode_results *results) +{ + switch (results->decode_type) { + default: + case UNKNOWN: Serial.print("UNKNOWN"); break ; + case NEC: Serial.print("NEC"); break ; + case SONY: Serial.print("SONY"); break ; + case RC5: Serial.print("RC5"); break ; + case RC6: Serial.print("RC6"); break ; + case DISH: Serial.print("DISH"); break ; + case SHARP: Serial.print("SHARP"); break ; + case JVC: Serial.print("JVC"); break ; + case SANYO: Serial.print("SANYO"); break ; + case MITSUBISHI: Serial.print("MITSUBISHI"); break ; + case SAMSUNG: Serial.print("SAMSUNG"); break ; + case LG: Serial.print("LG"); break ; + case WHYNTER: Serial.print("WHYNTER"); break ; + case AIWA_RC_T501: Serial.print("AIWA_RC_T501"); break ; + case PANASONIC: Serial.print("PANASONIC"); break ; + case DENON: Serial.print("Denon"); break ; + } +} + +//+============================================================================= +// Dump out the decode_results structure. +// +void dumpInfo (decode_results *results) +{ + // Check if the buffer overflowed + if (results->overflow) { + Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF"); + return; + } + + // Show Encoding standard + Serial.print("Encoding : "); + encoding(results); + Serial.println(""); + + // Show Code & length + Serial.print("Code : "); + ircode(results); + Serial.print(" ("); + Serial.print(results->bits, DEC); + Serial.println(" bits)"); +} + +//+============================================================================= +// Dump out the decode_results structure. +// +void dumpRaw (decode_results *results) +{ + // Print Raw data + Serial.print("Timing["); + Serial.print(results->rawlen-1, DEC); + Serial.println("]: "); + + for (int i = 1; i < results->rawlen; i++) { + unsigned long x = results->rawbuf[i] * USECPERTICK; + if (!(i & 1)) { // even + Serial.print("-"); + if (x < 1000) Serial.print(" ") ; + if (x < 100) Serial.print(" ") ; + Serial.print(x, DEC); + } else { // odd + Serial.print(" "); + Serial.print("+"); + if (x < 1000) Serial.print(" ") ; + if (x < 100) Serial.print(" ") ; + Serial.print(x, DEC); + if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one + } + if (!(i % 8)) Serial.println(""); + } + Serial.println(""); // Newline +} + +//+============================================================================= +// Dump out the decode_results structure. +// +void dumpCode (decode_results *results) +{ + // Start declaration + Serial.print("unsigned int "); // variable type + Serial.print("rawData["); // array name + Serial.print(results->rawlen - 1, DEC); // array size + Serial.print("] = {"); // Start declaration + + // Dump data + for (int i = 1; i < results->rawlen; i++) { + Serial.print(results->rawbuf[i] * USECPERTICK, DEC); + if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one + if (!(i & 1)) Serial.print(" "); + } + + // End declaration + Serial.print("};"); // + + // Comment + Serial.print(" // "); + encoding(results); + Serial.print(" "); + ircode(results); + + // Newline + Serial.println(""); + + // Now dump "known" codes + if (results->decode_type != UNKNOWN) { + + // Some protocols have an address + if (results->decode_type == PANASONIC) { + Serial.print("unsigned int addr = 0x"); + Serial.print(results->address, HEX); + Serial.println(";"); + } + + // All protocols have data + Serial.print("unsigned int data = 0x"); + Serial.print(results->value, HEX); + Serial.println(";"); + } +} + +//+============================================================================= +// The repeating section of the code +// +void loop ( ) +{ + decode_results results; // Somewhere to store the results + + if (irrecv.decode(&results)) { // Grab an IR code + dumpInfo(&results); // Output the results + dumpRaw(&results); // Output the results in RAW format + dumpCode(&results); // Output the results as source code + Serial.println(""); // Blank line between entries + irrecv.resume(); // Prepare for the next value + } +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRrelay/IRrelay.ino b/Arduino_Code/Arduino-IRremote/examples/IRrelay/IRrelay.ino new file mode 100644 index 000000000..046fb5fa6 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRrelay/IRrelay.ino @@ -0,0 +1,85 @@ +/* + * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv + * An IR detector/demodulator must be connected to the input RECV_PIN. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + */ + +#include + +int RECV_PIN = 11; +int RELAY_PIN = 4; + +IRrecv irrecv(RECV_PIN); +decode_results results; + +// Dumps out the decode_results structure. +// Call this after IRrecv::decode() +// void * to work around compiler issue +//void dump(void *v) { +// decode_results *results = (decode_results *)v +void dump(decode_results *results) { + int count = results->rawlen; + if (results->decode_type == UNKNOWN) { + Serial.println("Could not decode message"); + } + else { + if (results->decode_type == NEC) { + Serial.print("Decoded NEC: "); + } + else if (results->decode_type == SONY) { + Serial.print("Decoded SONY: "); + } + else if (results->decode_type == RC5) { + Serial.print("Decoded RC5: "); + } + else if (results->decode_type == RC6) { + Serial.print("Decoded RC6: "); + } + Serial.print(results->value, HEX); + Serial.print(" ("); + Serial.print(results->bits, DEC); + Serial.println(" bits)"); + } + Serial.print("Raw ("); + Serial.print(count, DEC); + Serial.print("): "); + + for (int i = 0; i < count; i++) { + if ((i % 2) == 1) { + Serial.print(results->rawbuf[i]*USECPERTICK, DEC); + } + else { + Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); + } + Serial.print(" "); + } + Serial.println(""); +} + +void setup() +{ + pinMode(RELAY_PIN, OUTPUT); + pinMode(13, OUTPUT); + Serial.begin(9600); + irrecv.enableIRIn(); // Start the receiver +} + +int on = 0; +unsigned long last = millis(); + +void loop() { + if (irrecv.decode(&results)) { + // If it's been at least 1/4 second since the last + // IR received, toggle the relay + if (millis() - last > 250) { + on = !on; + digitalWrite(RELAY_PIN, on ? HIGH : LOW); + digitalWrite(13, on ? HIGH : LOW); + dump(&results); + } + last = millis(); + irrecv.resume(); // Receive the next value + } +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRremoteInfo/IRremoteInfo.ino b/Arduino_Code/Arduino-IRremote/examples/IRremoteInfo/IRremoteInfo.ino new file mode 100644 index 000000000..2a269d948 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRremoteInfo/IRremoteInfo.ino @@ -0,0 +1,230 @@ +/* + * IRremote: IRremoteInfo - prints relevant config info & settings for IRremote over serial + * Intended to help identify & troubleshoot the various settings of IRremote + * For example, sometimes users are unsure of which pin is used for Tx or the RAWBUF values + * This example can be used to assist the user directly or with support. + * Intended to help identify & troubleshoot the various settings of IRremote + * Hopefully this utility will be a useful tool for support & troubleshooting for IRremote + * Check out the blog post describing the sketch via http://www.analysir.com/blog/2015/11/28/helper-utility-for-troubleshooting-irremote/ + * Version 1.0 November 2015 + * Original Author: AnalysIR - IR software & modules for Makers & Pros, visit http://www.AnalysIR.com + */ + + +#include + +void setup() +{ + Serial.begin(115200); //You may alter the BAUD rate here as needed + while (!Serial); //wait until Serial is established - required on some Platforms + + //Runs only once per restart of the Arduino. + dumpHeader(); + dumpRAWBUF(); + dumpTIMER(); + dumpTimerPin(); + dumpClock(); + dumpPlatform(); + dumpPulseParams(); + dumpSignalParams(); + dumpArduinoIDE(); + dumpDebugMode(); + dumpProtocols(); + dumpFooter(); +} + +void loop() { + //nothing to do! +} + +void dumpRAWBUF() { + Serial.print(F("RAWBUF: ")); + Serial.println(RAWBUF); +} + +void dumpTIMER() { + boolean flag = false; +#ifdef IR_USE_TIMER1 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer1")); flag = true; +#endif +#ifdef IR_USE_TIMER2 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer2")); flag = true; +#endif +#ifdef IR_USE_TIMER3 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer3")); flag = true; +#endif +#ifdef IR_USE_TIMER4 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4")); flag = true; +#endif +#ifdef IR_USE_TIMER5 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer5")); flag = true; +#endif +#ifdef IR_USE_TIMER4_HS + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer4_HS")); flag = true; +#endif +#ifdef IR_USE_TIMER_CMT + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_CMT")); flag = true; +#endif +#ifdef IR_USE_TIMER_TPM1 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TPM1")); flag = true; +#endif +#ifdef IR_USE_TIMER_TINY0 + Serial.print(F("Timer defined for use: ")); Serial.println(F("Timer_TINY0")); flag = true; +#endif + + if (!flag) { + Serial.print(F("Timer Error: ")); Serial.println(F("not defined")); + } +} + +void dumpTimerPin() { + Serial.print(F("IR Tx Pin: ")); + Serial.println(TIMER_PWM_PIN); +} + +void dumpClock() { + Serial.print(F("MCU Clock: ")); + Serial.println(F_CPU); +} + +void dumpPlatform() { + Serial.print(F("MCU Platform: ")); + +#if defined(__AVR_ATmega1280__) + Serial.println(F("Arduino Mega1280")); +#elif defined(__AVR_ATmega2560__) + Serial.println(F("Arduino Mega2560")); +#elif defined(__AVR_AT90USB162__) + Serial.println(F("Teensy 1.0 / AT90USB162")); + // Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + Serial.println(F("Arduino Leonardo / Yun / Teensy 1.0 / ATmega32U4")); +#elif defined(__MK20DX128__) || defined(__MK20DX256__) + Serial.println(F("Teensy 3.0 / Teensy 3.1 / MK20DX128 / MK20DX256")); +#elif defined(__MKL26Z64__) + Serial.println(F("Teensy-LC / MKL26Z64")); +#elif defined(__AVR_AT90USB646__) + Serial.println(F("Teensy++ 1.0 / AT90USB646")); +#elif defined(__AVR_AT90USB1286__) + Serial.println(F("Teensy++ 2.0 / AT90USB1286")); +#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) + Serial.println(F("ATmega1284")); +#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) + Serial.println(F("ATmega644")); +#elif defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324PA__) + Serial.println(F("ATmega324")); +#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) + Serial.println(F("ATmega164")); +#elif defined(__AVR_ATmega128__) + Serial.println(F("ATmega128")); +#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega88P__) + Serial.println(F("ATmega88")); +#elif defined(__AVR_ATmega64__) + Serial.println(F("ATmega64")); +#elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega48P__) + Serial.println(F("ATmega48")); +#elif defined(__AVR_ATmega32__) + Serial.println(F("ATmega32")); +#elif defined(__AVR_ATmega16__) + Serial.println(F("ATmega16")); +#elif defined(__AVR_ATmega8535__) + Serial.println(F("ATmega8535")); +#elif defined(__AVR_ATmega8__) + Serial.println(F("Atmega8")); +#elif defined(__AVR_ATtiny84__) + Serial.println(F("ATtiny84")); +#elif defined(__AVR_ATtiny85__) + Serial.println(F("ATtiny85")); +#else + Serial.println(F("ATmega328(P) / (Duemilanove, Diecimila, LilyPad, Mini, Micro, Fio, Nano, etc)")); +#endif +} + +void dumpPulseParams() { + Serial.print(F("Mark Excess: ")); Serial.print(MARK_EXCESS);; Serial.println(F(" uSecs")); + Serial.print(F("Microseconds per tick: ")); Serial.print(USECPERTICK);; Serial.println(F(" uSecs")); + Serial.print(F("Measurement tolerance: ")); Serial.print(TOLERANCE); Serial.println(F("%")); +} + +void dumpSignalParams() { + Serial.print(F("Minimum Gap between IR Signals: ")); Serial.print(_GAP); Serial.println(F(" uSecs")); +} + +void dumpDebugMode() { + Serial.print(F("Debug Mode: ")); +#if DEBUG + Serial.println(F("ON")); +#else + Serial.println(F("OFF (Normal)")); +#endif + +} + +void dumpArduinoIDE() { + Serial.print(F("Arduino IDE version: ")); + Serial.print(ARDUINO / 10000); + Serial.write('.'); + Serial.print((ARDUINO % 10000) / 100); + Serial.write('.'); + Serial.println(ARDUINO % 100); +} + +void dumpProtocols() { + + Serial.println(); Serial.print(F("IR PROTOCOLS ")); Serial.print(F("SEND ")); Serial.println(F("DECODE")); + Serial.print(F("============= ")); Serial.print(F("======== ")); Serial.println(F("========")); + Serial.print(F("RC5: ")); printSendEnabled(SEND_RC5); printDecodeEnabled(DECODE_RC6); + Serial.print(F("RC6: ")); printSendEnabled(SEND_RC6); printDecodeEnabled(DECODE_RC5); + Serial.print(F("NEC: ")); printSendEnabled(SEND_NEC); printDecodeEnabled(DECODE_NEC); + Serial.print(F("SONY: ")); printSendEnabled(SEND_SONY); printDecodeEnabled(DECODE_SONY); + Serial.print(F("PANASONIC: ")); printSendEnabled(SEND_PANASONIC); printDecodeEnabled(DECODE_PANASONIC); + Serial.print(F("JVC: ")); printSendEnabled(SEND_JVC); printDecodeEnabled(DECODE_JVC); + Serial.print(F("SAMSUNG: ")); printSendEnabled(SEND_SAMSUNG); printDecodeEnabled(DECODE_SAMSUNG); + Serial.print(F("WHYNTER: ")); printSendEnabled(SEND_WHYNTER); printDecodeEnabled(DECODE_WHYNTER); + Serial.print(F("AIWA_RC_T501: ")); printSendEnabled(SEND_AIWA_RC_T501); printDecodeEnabled(DECODE_AIWA_RC_T501); + Serial.print(F("LG: ")); printSendEnabled(SEND_LG); printDecodeEnabled(DECODE_LG); + Serial.print(F("SANYO: ")); printSendEnabled(SEND_SANYO); printDecodeEnabled(DECODE_SANYO); + Serial.print(F("MITSUBISHI: ")); printSendEnabled(SEND_MITSUBISHI); printDecodeEnabled(DECODE_MITSUBISHI); + Serial.print(F("DISH: ")); printSendEnabled(SEND_DISH); printDecodeEnabled(DECODE_DISH); + Serial.print(F("SHARP: ")); printSendEnabled(SEND_SHARP); printDecodeEnabled(DECODE_SHARP); + Serial.print(F("DENON: ")); printSendEnabled(SEND_DENON); printDecodeEnabled(DECODE_DENON); + Serial.print(F("PRONTO: ")); printSendEnabled(SEND_PRONTO); Serial.println(F("(Not Applicable)")); +} + +void printSendEnabled(int flag) { + if (flag) { + Serial.print(F("Enabled ")); + } + else { + Serial.print(F("Disabled ")); + } +} + +void printDecodeEnabled(int flag) { + if (flag) { + Serial.println(F("Enabled")); + } + else { + Serial.println(F("Disabled")); + } +} + +void dumpHeader() { + Serial.println(F("IRremoteInfo - by AnalysIR (http://www.AnalysIR.com/)")); + Serial.println(F(" - A helper sketch to assist in troubleshooting issues with the library by reviewing the settings within the IRremote library")); + Serial.println(F(" - Prints out the important settings within the library, which can be configured to suit the many supported platforms")); + Serial.println(F(" - When seeking on-line support, please post or upload the output of this sketch, where appropriate")); + Serial.println(); + Serial.println(F("IRremote Library Settings")); + Serial.println(F("=========================")); +} + +void dumpFooter() { + Serial.println(); + Serial.println(F("Notes: ")); + Serial.println(F(" - Most of the seetings above can be configured in the following files included as part of the library")); + Serial.println(F(" - IRremteInt.h")); + Serial.println(F(" - IRremote.h")); + Serial.println(F(" - You can save SRAM by disabling the Decode or Send features for any protocol (Near the top of IRremoteInt.h)")); + Serial.println(F(" - Some Timer conflicts, with other libraries, can be easily resolved by configuring a differnt Timer for your platform")); +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRsendDemo/IRsendDemo.ino b/Arduino_Code/Arduino-IRremote/examples/IRsendDemo/IRsendDemo.ino new file mode 100644 index 000000000..4f23af6cf --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRsendDemo/IRsendDemo.ino @@ -0,0 +1,24 @@ +/* + * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend + * An IR LED must be connected to Arduino PWM pin 3. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + */ + + +#include + +IRsend irsend; + +void setup() +{ +} + +void loop() { + for (int i = 0; i < 3; i++) { + irsend.sendSony(0xa90, 12); + delay(40); + } + delay(5000); //5 second delay between each signal burst +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino b/Arduino_Code/Arduino-IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino new file mode 100644 index 000000000..e83d6e6df --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRsendRawDemo/IRsendRawDemo.ino @@ -0,0 +1,37 @@ +/* + * IRremote: IRsendRawDemo - demonstrates sending IR codes with sendRaw + * An IR LED must be connected to Arduino PWM pin 3. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + * + * IRsendRawDemo - added by AnalysIR (via www.AnalysIR.com), 24 August 2015 + * + * This example shows how to send a RAW signal using the IRremote library. + * The example signal is actually a 32 bit NEC signal. + * Remote Control button: LGTV Power On/Off. + * Hex Value: 0x20DF10EF, 32 bits + * + * It is more efficient to use the sendNEC function to send NEC signals. + * Use of sendRaw here, serves only as an example of using the function. + * + */ + + +#include + +IRsend irsend; + +void setup() +{ + +} + +void loop() { + int khz = 38; // 38kHz carrier frequency for the NEC protocol + unsigned int irSignal[] = {9000, 4500, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 560, 560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 39416, 9000, 2210, 560}; //AnalysIR Batch Export (IRremote) - RAW + + irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz); //Note the approach used to automatically calculate the size of the array. + + delay(5000); //In this example, the signal will be repeated every 5 seconds, approximately. +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRtest/IRtest.ino b/Arduino_Code/Arduino-IRremote/examples/IRtest/IRtest.ino new file mode 100644 index 000000000..4845a4a4d --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRtest/IRtest.ino @@ -0,0 +1,190 @@ +/* + * IRremote: IRtest unittest + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + * + * Note: to run these tests, edit IRremote/IRremote.h to add "#define TEST" + * You must then recompile the library by removing IRremote.o and restarting + * the arduino IDE. + */ + +#include +#include + +// Dumps out the decode_results structure. +// Call this after IRrecv::decode() +// void * to work around compiler issue +//void dump(void *v) { +// decode_results *results = (decode_results *)v +void dump(decode_results *results) { + int count = results->rawlen; + if (results->decode_type == UNKNOWN) { + Serial.println("Could not decode message"); + } + else { + if (results->decode_type == NEC) { + Serial.print("Decoded NEC: "); + } + else if (results->decode_type == SONY) { + Serial.print("Decoded SONY: "); + } + else if (results->decode_type == RC5) { + Serial.print("Decoded RC5: "); + } + else if (results->decode_type == RC6) { + Serial.print("Decoded RC6: "); + } + Serial.print(results->value, HEX); + Serial.print(" ("); + Serial.print(results->bits, DEC); + Serial.println(" bits)"); + } + Serial.print("Raw ("); + Serial.print(count, DEC); + Serial.print("): "); + + for (int i = 0; i < count; i++) { + if ((i % 2) == 1) { + Serial.print(results->rawbuf[i]*USECPERTICK, DEC); + } + else { + Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); + } + Serial.print(" "); + } + Serial.println(""); +} + +IRrecv irrecv(0); +decode_results results; + +class IRsendDummy : +public IRsend +{ +public: + // For testing, just log the marks/spaces +#define SENDLOG_LEN 128 + int sendlog[SENDLOG_LEN]; + int sendlogcnt; + IRsendDummy() : + IRsend() { + } + void reset() { + sendlogcnt = 0; + } + void mark(int time) { + sendlog[sendlogcnt] = time; + if (sendlogcnt < SENDLOG_LEN) sendlogcnt++; + } + void space(int time) { + sendlog[sendlogcnt] = -time; + if (sendlogcnt < SENDLOG_LEN) sendlogcnt++; + } + // Copies the dummy buf into the interrupt buf + void useDummyBuf() { + int last = SPACE; + irparams.rcvstate = STATE_STOP; + irparams.rawlen = 1; // Skip the gap + for (int i = 0 ; i < sendlogcnt; i++) { + if (sendlog[i] < 0) { + if (last == MARK) { + // New space + irparams.rawbuf[irparams.rawlen++] = (-sendlog[i] - MARK_EXCESS) / USECPERTICK; + last = SPACE; + } + else { + // More space + irparams.rawbuf[irparams.rawlen - 1] += -sendlog[i] / USECPERTICK; + } + } + else if (sendlog[i] > 0) { + if (last == SPACE) { + // New mark + irparams.rawbuf[irparams.rawlen++] = (sendlog[i] + MARK_EXCESS) / USECPERTICK; + last = MARK; + } + else { + // More mark + irparams.rawbuf[irparams.rawlen - 1] += sendlog[i] / USECPERTICK; + } + } + } + if (irparams.rawlen % 2) { + irparams.rawlen--; // Remove trailing space + } + } +}; + +IRsendDummy irsenddummy; + +void verify(unsigned long val, int bits, int type) { + irsenddummy.useDummyBuf(); + irrecv.decode(&results); + Serial.print("Testing "); + Serial.print(val, HEX); + if (results.value == val && results.bits == bits && results.decode_type == type) { + Serial.println(": OK"); + } + else { + Serial.println(": Error"); + dump(&results); + } +} + +void testNEC(unsigned long val, int bits) { + irsenddummy.reset(); + irsenddummy.sendNEC(val, bits); + verify(val, bits, NEC); +} +void testSony(unsigned long val, int bits) { + irsenddummy.reset(); + irsenddummy.sendSony(val, bits); + verify(val, bits, SONY); +} +void testRC5(unsigned long val, int bits) { + irsenddummy.reset(); + irsenddummy.sendRC5(val, bits); + verify(val, bits, RC5); +} +void testRC6(unsigned long val, int bits) { + irsenddummy.reset(); + irsenddummy.sendRC6(val, bits); + verify(val, bits, RC6); +} + +void test() { + Serial.println("NEC tests"); + testNEC(0x00000000, 32); + testNEC(0xffffffff, 32); + testNEC(0xaaaaaaaa, 32); + testNEC(0x55555555, 32); + testNEC(0x12345678, 32); + Serial.println("Sony tests"); + testSony(0xfff, 12); + testSony(0x000, 12); + testSony(0xaaa, 12); + testSony(0x555, 12); + testSony(0x123, 12); + Serial.println("RC5 tests"); + testRC5(0xfff, 12); + testRC5(0x000, 12); + testRC5(0xaaa, 12); + testRC5(0x555, 12); + testRC5(0x123, 12); + Serial.println("RC6 tests"); + testRC6(0xfffff, 20); + testRC6(0x00000, 20); + testRC6(0xaaaaa, 20); + testRC6(0x55555, 20); + testRC6(0x12345, 20); +} + +void setup() +{ + Serial.begin(9600); + test(); +} + +void loop() { +} diff --git a/Arduino_Code/Arduino-IRremote/examples/IRtest2/IRtest2.ino b/Arduino_Code/Arduino-IRremote/examples/IRtest2/IRtest2.ino new file mode 100644 index 000000000..22a8fa2f8 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/IRtest2/IRtest2.ino @@ -0,0 +1,290 @@ +/* + * Test send/receive functions of IRremote, using a pair of Arduinos. + * + * Arduino #1 should have an IR LED connected to the send pin (3). + * Arduino #2 should have an IR detector/demodulator connected to the + * receive pin (11) and a visible LED connected to pin 3. + * + * The cycle: + * Arduino #1 will wait 2 seconds, then run through the tests. + * It repeats this forever. + * Arduino #2 will wait for at least one second of no signal + * (to synchronize with #1). It will then wait for the same test + * signals. It will log all the status to the serial port. It will + * also indicate status through the LED, which will flash each time a test + * is completed. If there is an error, it will light up for 5 seconds. + * + * The test passes if the LED flashes 19 times, pauses, and then repeats. + * The test fails if the LED lights for 5 seconds. + * + * The test software automatically decides which board is the sender and which is + * the receiver by looking for an input on the send pin, which will indicate + * the sender. You should hook the serial port to the receiver for debugging. + * + * Copyright 2010 Ken Shirriff + * http://arcfn.com + */ + +#include + +int RECV_PIN = 11; +int LED_PIN = 3; + +IRrecv irrecv(RECV_PIN); +IRsend irsend; + +decode_results results; + +#define RECEIVER 1 +#define SENDER 2 +#define ERROR 3 + +int mode; + +void setup() +{ + Serial.begin(9600); + // Check RECV_PIN to decide if we're RECEIVER or SENDER + if (digitalRead(RECV_PIN) == HIGH) { + mode = RECEIVER; + irrecv.enableIRIn(); + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); + Serial.println("Receiver mode"); + } + else { + mode = SENDER; + Serial.println("Sender mode"); + } +} + +// Wait for the gap between tests, to synchronize with +// the sender. +// Specifically, wait for a signal followed by a gap of at last gap ms. +void waitForGap(unsigned long gap) { + Serial.println("Waiting for gap"); + while (1) { + while (digitalRead(RECV_PIN) == LOW) { + } + unsigned long time = millis(); + while (digitalRead(RECV_PIN) == HIGH) { + if (millis() - time > gap) { + return; + } + } + } +} + +// Dumps out the decode_results structure. +// Call this after IRrecv::decode() +void dump(decode_results *results) { + int count = results->rawlen; + if (results->decode_type == UNKNOWN) { + Serial.println("Could not decode message"); + } + else { + if (results->decode_type == NEC) { + Serial.print("Decoded NEC: "); + } + else if (results->decode_type == SONY) { + Serial.print("Decoded SONY: "); + } + else if (results->decode_type == RC5) { + Serial.print("Decoded RC5: "); + } + else if (results->decode_type == RC6) { + Serial.print("Decoded RC6: "); + } + Serial.print(results->value, HEX); + Serial.print(" ("); + Serial.print(results->bits, DEC); + Serial.println(" bits)"); + } + Serial.print("Raw ("); + Serial.print(count, DEC); + Serial.print("): "); + + for (int i = 0; i < count; i++) { + if ((i % 2) == 1) { + Serial.print(results->rawbuf[i]*USECPERTICK, DEC); + } + else { + Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC); + } + Serial.print(" "); + } + Serial.println(""); +} + + +// Test send or receive. +// If mode is SENDER, send a code of the specified type, value, and bits +// If mode is RECEIVER, receive a code and verify that it is of the +// specified type, value, and bits. For success, the LED is flashed; +// for failure, the mode is set to ERROR. +// The motivation behind this method is that the sender and the receiver +// can do the same test calls, and the mode variable indicates whether +// to send or receive. +void test(const char *label, int type, unsigned long value, int bits) { + if (mode == SENDER) { + Serial.println(label); + if (type == NEC) { + irsend.sendNEC(value, bits); + } + else if (type == SONY) { + irsend.sendSony(value, bits); + } + else if (type == RC5) { + irsend.sendRC5(value, bits); + } + else if (type == RC6) { + irsend.sendRC6(value, bits); + } + else { + Serial.print(label); + Serial.println("Bad type!"); + } + delay(200); + } + else if (mode == RECEIVER) { + irrecv.resume(); // Receive the next value + unsigned long max_time = millis() + 30000; + Serial.print(label); + + // Wait for decode or timeout + while (!irrecv.decode(&results)) { + if (millis() > max_time) { + Serial.println("Timeout receiving data"); + mode = ERROR; + return; + } + } + if (type == results.decode_type && value == results.value && bits == results.bits) { + Serial.println (": OK"); + digitalWrite(LED_PIN, HIGH); + delay(20); + digitalWrite(LED_PIN, LOW); + } + else { + Serial.println(": BAD"); + dump(&results); + mode = ERROR; + } + } +} + +// Test raw send or receive. This is similar to the test method, +// except it send/receives raw data. +void testRaw(const char *label, unsigned int *rawbuf, int rawlen) { + if (mode == SENDER) { + Serial.println(label); + irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */); + delay(200); + } + else if (mode == RECEIVER ) { + irrecv.resume(); // Receive the next value + unsigned long max_time = millis() + 30000; + Serial.print(label); + + // Wait for decode or timeout + while (!irrecv.decode(&results)) { + if (millis() > max_time) { + Serial.println("Timeout receiving data"); + mode = ERROR; + return; + } + } + + // Received length has extra first element for gap + if (rawlen != results.rawlen - 1) { + Serial.print("Bad raw length "); + Serial.println(results.rawlen, DEC); + mode = ERROR; + return; + } + for (int i = 0; i < rawlen; i++) { + long got = results.rawbuf[i+1] * USECPERTICK; + // Adjust for extra duration of marks + if (i % 2 == 0) { + got -= MARK_EXCESS; + } + else { + got += MARK_EXCESS; + } + // See if close enough, within 25% + if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) { + Serial.println(": BAD"); + dump(&results); + mode = ERROR; + return; + } + + } + Serial.println (": OK"); + digitalWrite(LED_PIN, HIGH); + delay(20); + digitalWrite(LED_PIN, LOW); + } +} + +// This is the raw data corresponding to NEC 0x12345678 +unsigned int sendbuf[] = { /* NEC format */ + 9000, 4500, + 560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */ + 560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */ + 560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */ + 560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */ + 560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */ + 560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */ + 560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */ + 560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */ + 560}; + +void loop() { + if (mode == SENDER) { + delay(2000); // Delay for more than gap to give receiver a better chance to sync. + } + else if (mode == RECEIVER) { + waitForGap(1000); + } + else if (mode == ERROR) { + // Light up for 5 seconds for error + digitalWrite(LED_PIN, HIGH); + delay(5000); + digitalWrite(LED_PIN, LOW); + mode = RECEIVER; // Try again + return; + } + + // The test suite. + test("SONY1", SONY, 0x123, 12); + test("SONY2", SONY, 0x000, 12); + test("SONY3", SONY, 0xfff, 12); + test("SONY4", SONY, 0x12345, 20); + test("SONY5", SONY, 0x00000, 20); + test("SONY6", SONY, 0xfffff, 20); + test("NEC1", NEC, 0x12345678, 32); + test("NEC2", NEC, 0x00000000, 32); + test("NEC3", NEC, 0xffffffff, 32); + test("NEC4", NEC, REPEAT, 32); + test("RC51", RC5, 0x12345678, 32); + test("RC52", RC5, 0x0, 32); + test("RC53", RC5, 0xffffffff, 32); + test("RC61", RC6, 0x12345678, 32); + test("RC62", RC6, 0x0, 32); + test("RC63", RC6, 0xffffffff, 32); + + // Tests of raw sending and receiving. + // First test sending raw and receiving raw. + // Then test sending raw and receiving decoded NEC + // Then test sending NEC and receiving raw + testRaw("RAW1", sendbuf, 67); + if (mode == SENDER) { + testRaw("RAW2", sendbuf, 67); + test("RAW3", NEC, 0x12345678, 32); + } + else { + test("RAW2", NEC, 0x12345678, 32); + testRaw("RAW3", sendbuf, 67); + } +} diff --git a/Arduino_Code/Arduino-IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/Arduino_Code/Arduino-IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino new file mode 100644 index 000000000..33c167c58 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino @@ -0,0 +1,29 @@ +/* + * IRremote: IRsendDemo - demonstrates sending IR codes with IRsend + * An IR LED must be connected to Arduino PWM pin 3. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) + */ +#include + +#define PanasonicAddress 0x4004 // Panasonic address (Pre data) +#define PanasonicPower 0x100BCBD // Panasonic Power button + +#define JVCPower 0xC5E8 + +IRsend irsend; + +void setup() +{ +} + +void loop() { + irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off + + irsend.sendJVC(JVCPower, 16,0); // hex value, 16 bits, no repeat + delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information + irsend.sendJVC(JVCPower, 16,1); // hex value, 16 bits, repeat + delayMicroseconds(50); +} diff --git a/Arduino_Code/Arduino-IRremote/examples/LGACSendDemo/LGACSendDemo.ino b/Arduino_Code/Arduino-IRremote/examples/LGACSendDemo/LGACSendDemo.ino new file mode 100644 index 000000000..e3c7dfa3d --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/LGACSendDemo/LGACSendDemo.ino @@ -0,0 +1,263 @@ +#include +#include + + +IRsend irsend; +// not used +int RECV_PIN = 11; +IRrecv irrecv (RECV_PIN); + +const int AC_TYPE = 0; +// 0 : TOWER +// 1 : WALL +// + +int AC_HEAT = 0; +// 0 : cooling +// 1 : heating + +int AC_POWER_ON = 0; +// 0 : off +// 1 : on + +int AC_AIR_ACLEAN = 0; +// 0 : off +// 1 : on --> power on + +int AC_TEMPERATURE = 27; +// temperature : 18 ~ 30 + +int AC_FLOW = 1; +// 0 : low +// 1 : mid +// 2 : high +// if AC_TYPE =1, 3 : change +// + + +const int AC_FLOW_TOWER[3] = {0, 4, 6}; +const int AC_FLOW_WALL[4] = {0, 2, 4, 5}; + +unsigned long AC_CODE_TO_SEND; + +int r = LOW; +int o_r = LOW; + +byte a, b; + +void ac_send_code(unsigned long code) +{ + Serial.print("code to send : "); + Serial.print(code, BIN); + Serial.print(" : "); + Serial.println(code, HEX); + + irsend.sendLG(code, 28); +} + +void ac_activate(int temperature, int air_flow) +{ + + int AC_MSBITS1 = 8; + int AC_MSBITS2 = 8; + int AC_MSBITS3 = 0; + int AC_MSBITS4 ; + if ( AC_HEAT == 1 ) { + // heating + AC_MSBITS4 = 4; + } else { + // cooling + AC_MSBITS4 = 0; + } + int AC_MSBITS5 = temperature - 15; + int AC_MSBITS6 ; + + if ( AC_TYPE == 0) { + AC_MSBITS6 = AC_FLOW_TOWER[air_flow]; + } else { + AC_MSBITS6 = AC_FLOW_WALL[air_flow]; + } + + int AC_MSBITS7 = (AC_MSBITS3 + AC_MSBITS4 + AC_MSBITS5 + AC_MSBITS6) & B00001111; + + AC_CODE_TO_SEND = AC_MSBITS1 << 4 ; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS2) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS3) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS4) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS5) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS6) << 4; + AC_CODE_TO_SEND = (AC_CODE_TO_SEND + AC_MSBITS7); + + ac_send_code(AC_CODE_TO_SEND); + + AC_POWER_ON = 1; + AC_TEMPERATURE = temperature; + AC_FLOW = air_flow; +} + +void ac_change_air_swing(int air_swing) +{ + if ( AC_TYPE == 0) { + if ( air_swing == 1) { + AC_CODE_TO_SEND = 0x881316B; + } else { + AC_CODE_TO_SEND = 0x881317C; + } + } else { + if ( air_swing == 1) { + AC_CODE_TO_SEND = 0x8813149; + } else { + AC_CODE_TO_SEND = 0x881315A; + } + } + + ac_send_code(AC_CODE_TO_SEND); +} + +void ac_power_down() +{ + AC_CODE_TO_SEND = 0x88C0051; + + ac_send_code(AC_CODE_TO_SEND); + + AC_POWER_ON = 0; +} + +void ac_air_clean(int air_clean) +{ + if ( air_clean == 1) { + AC_CODE_TO_SEND = 0x88C000C; + } else { + AC_CODE_TO_SEND = 0x88C0084; + } + + ac_send_code(AC_CODE_TO_SEND); + + AC_AIR_ACLEAN = air_clean; +} + +void setup() +{ + Serial.begin(38400); + delay(1000); + Wire.begin(7); + Wire.onReceive(receiveEvent); + + Serial.println(" - - - T E S T - - - "); + + /* test + ac_activate(25, 1); + delay(5000); + ac_activate(27, 2); + delay(5000); + + */ +} + +void loop() +{ + + + ac_activate(25, 1); + delay(5000); + ac_activate(27, 0); + delay(5000); + + + if ( r != o_r) { + + /* + # a : mode or temp b : air_flow, temp, swing, clean, cooling/heating + # 18 ~ 30 : temp 0 ~ 2 : flow // on + # 0 : off 0 + # 1 : on 0 + # 2 : air_swing 0 or 1 + # 3 : air_clean 0 or 1 + # 4 : air_flow 0 ~ 2 : flow + # 5 : temp 18 ~ 30 + # + : temp + 1 + # - : temp - 1 + # m : change cooling to air clean, air clean to cooling + */ + Serial.print("a : "); + Serial.print(a); + Serial.print(" b : "); + Serial.println(b); + + switch (a) { + case 0: // off + ac_power_down(); + break; + case 1: // on + ac_activate(AC_TEMPERATURE, AC_FLOW); + break; + case 2: + if ( b == 0 || b == 1 ) { + ac_change_air_swing(b); + } + break; + case 3: // 1 : clean on, power on + if ( b == 0 || b == 1 ) { + ac_air_clean(b); + } + break; + case 4: + if ( 0 <= b && b <= 2 ) { + ac_activate(AC_TEMPERATURE, b); + } + break; + case 5: + if (18 <= b && b <= 30 ) { + ac_activate(b, AC_FLOW); + } + break; + case '+': + if ( 18 <= AC_TEMPERATURE && AC_TEMPERATURE <= 29 ) { + ac_activate((AC_TEMPERATURE + 1), AC_FLOW); + } + break; + case '-': + if ( 19 <= AC_TEMPERATURE && AC_TEMPERATURE <= 30 ) { + ac_activate((AC_TEMPERATURE - 1), AC_FLOW); + } + break; + case 'm': + /* + if ac is on, 1) turn off, 2) turn on ac_air_clean(1) + if ac is off, 1) turn on, 2) turn off ac_air_clean(0) + */ + if ( AC_POWER_ON == 1 ) { + ac_power_down(); + delay(100); + ac_air_clean(1); + } else { + if ( AC_AIR_ACLEAN == 1) { + ac_air_clean(0); + delay(100); + } + ac_activate(AC_TEMPERATURE, AC_FLOW); + } + break; + default: + if ( 18 <= a && a <= 30 ) { + if ( 0 <= b && b <= 2 ) { + ac_activate(a, b); + } + } + } + + o_r = r ; + } + delay(100); +} + + + +void receiveEvent(int howMany) +{ + a = Wire.read(); + b = Wire.read(); + r = !r ; +} + + diff --git a/Arduino_Code/Arduino-IRremote/examples/LGACSendDemo/LGACSendDemo.md b/Arduino_Code/Arduino-IRremote/examples/LGACSendDemo/LGACSendDemo.md new file mode 100644 index 000000000..62c707316 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/LGACSendDemo/LGACSendDemo.md @@ -0,0 +1,93 @@ +=== decoding for LG A/C ==== +- 1) remote of LG AC has two type of HDR mark/space, 8000/4000 and 3100/10000 +- 2) HDR 8000/4000 is decoded using decodeLG(IRrecvDumpV2) without problem +- 3) for HDR 3100/10000, use AnalysIR's code : http://www.analysir.com/blog/2014/03/19/air-conditioners-problems-recording-long-infrared-remote-control-signals-arduino/ +- 4) for bin output based on AnalysIR's code : https://gist.github.com/chaeplin/a3a4b4b6b887c663bfe8 +- 5) remove first two byte(11) +- 6) sample rawcode with bin output : https://gist.github.com/chaeplin/134d232e0b8cfb898860 + + +=== *** === +- 1) Sample raw code : https://gist.github.com/chaeplin/ab2a7ad1533c41260f0d +- 2) send raw code : https://gist.github.com/chaeplin/7c800d3166463bb51be4 + + +=== *** === +- (0) : Cooling or Heating +- (1) : fixed +- (2) : fixed +- (3) : special(power, swing, air clean) +- (4) : change air flow, temperature, cooling(0)/heating(4) +- (5) : temperature ( 15 + (5) = ) +- (6) : air flow +- (7) : crc ( 3 + 4 + 5 + 6 ) & B00001111 + + +°F = °C × 1.8 + 32 +°C = (°F − 32) / 1.8 + + +=== *** === +* remote / Korea / without heating + +| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|---|----|----|----|----|----|----|---- +| on / 25 / mid | C |1000|1000|0000|0000|1010|0010|1100 +| on / 26 / mid | C |1000|1000|0000|0000|1011|0010|1101 +| on / 27 / mid | C |1000|1000|0000|0000|1100|0010|1110 +| on / 28 / mid | C |1000|1000|0000|0000|1101|0010|1111 +| on / 25 / high | C |1000|1000|0000|0000|1010|0100|1110 +| on / 26 / high | C |1000|1000|0000|0000|1011|0100|1111 +| on / 27 / high | C |1000|1000|0000|0000|1100|0100|0000 +| on / 28 / high | C |1000|1000|0000|0000|1101|0100|0001 +|----------------|---|----|----|----|----|----|----|---- +| 1 up | C |1000|1000|0000|1000|1101|0100|1001 +|----------------|---|----|----|----|----|----|----|---- +| Cool power | C |1000|1000|0001|0000|0000|1100|1101 +| energy saving | C |1000|1000|0001|0000|0000|0100|0101 +| power | C |1000|1000|0001|0000|0000|1000|1001 +| flow/up/down | C |1000|1000|0001|0011|0001|0100|1001 +| up/down off | C |1000|1000|0001|0011|0001|0101|1010 +| flow/left/right| C |1000|1000|0001|0011|0001|0110|1011 +| left/right off | C |1000|1000|0001|0011|0001|0111|1100 +|----------------|---|----|----|----|----|----|----|---- +| Air clean | C |1000|1000|1100|0000|0000|0000|1100 +|----------------|---|----|----|----|----|----|----|---- +| off | C |1000|1000|1100|0000|0000|0101|0001 + + + +* remote / with heating +* converted using raw code at https://github.com/chaeplin/RaspAC/blob/master/lircd.conf + +| status |(0)| (1)| (2)| (3)| (4)| (5)| (6)| (7) +|----------------|---|----|----|----|----|----|----|---- +| on | C |1000|1000|0000|0000|1011|0010|1101 +|----------------|---|----|----|----|----|----|----|---- +| off | C |1000|1000|1100|0000|0000|0101|0001 +|----------------|---|----|----|----|----|----|----|---- +| 64 / 18 | C |1000|1000|0000|0000|0011|0100|0111 +| 66 / 19 | C |1000|1000|0000|0000|0100|0100|1000 +| 68 / 20 | C |1000|1000|0000|0000|0101|0100|1001 +| 70 / 21 | C |1000|1000|0000|0000|0110|0100|1010 +| 72 / 22 | C |1000|1000|0000|0000|0111|0100|1011 +| 74 / 23 | C |1000|1000|0000|0000|1000|0100|1100 +| 76 / 25 | C |1000|1000|0000|0000|1010|0100|1110 +| 78 / 26 | C |1000|1000|0000|0000|1011|0100|1111 +| 80 / 27 | C |1000|1000|0000|0000|1100|0100|0000 +| 82 / 28 | C |1000|1000|0000|0000|1101|0100|0001 +| 84 / 29 | C |1000|1000|0000|0000|1110|0100|0010 +| 86 / 30 | C |1000|1000|0000|0000|1111|0100|0011 +|----------------|---|----|----|----|----|----|----|---- +| heat64 | H |1000|1000|0000|0100|0011|0100|1011 +| heat66 | H |1000|1000|0000|0100|0100|0100|1100 +| heat68 | H |1000|1000|0000|0100|0101|0100|1101 +| heat70 | H |1000|1000|0000|0100|0110|0100|1110 +| heat72 | H |1000|1000|0000|0100|0111|0100|1111 +| heat74 | H |1000|1000|0000|0100|1000|0100|0000 +| heat76 | H |1000|1000|0000|0100|1001|0100|0001 +| heat78 | H |1000|1000|0000|0100|1011|0100|0011 +| heat80 | H |1000|1000|0000|0100|1100|0100|0100 +| heat82 | H |1000|1000|0000|0100|1101|0100|0101 +| heat84 | H |1000|1000|0000|0100|1110|0100|0110 +| heat86 | H |1000|1000|0000|0100|1111|0100|0111 diff --git a/Arduino_Code/Arduino-IRremote/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino b/Arduino_Code/Arduino-IRremote/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino new file mode 100644 index 000000000..e43d06c2e --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/LegoPowerFunctionsSendDemo/LegoPowerFunctionsSendDemo.ino @@ -0,0 +1,22 @@ +/* + * LegoPowerFunctionsSendDemo: LEGO Power Functions + * Copyright (c) 2016 Philipp Henkel + */ + +#include +#include + +IRsend irsend; + +void setup() { +} + +void loop() { + // Send repeated command "channel 1, blue forward, red backward" + irsend.sendLegoPowerFunctions(0x197); + delay(2000); + + // Send single command "channel 1, blue forward, red backward" + irsend.sendLegoPowerFunctions(0x197, false); + delay(2000); +} diff --git a/Arduino_Code/Arduino-IRremote/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino b/Arduino_Code/Arduino-IRremote/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino new file mode 100644 index 000000000..65760e2fd --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/examples/LegoPowerFunctionsTests/LegoPowerFunctionsTests.ino @@ -0,0 +1,193 @@ +/* + * LegoPowerFunctionsTest: LEGO Power Functions Tests + * Copyright (c) 2016, 2017 Philipp Henkel + */ + +#include + +void setup() { + Serial.begin(9600); + delay(1000); // wait for reset triggered by serial connection + runBitStreamEncoderTests(); +} + +void loop() { +} + +void runBitStreamEncoderTests() { + Serial.println(); + Serial.println("BitStreamEncoder Tests"); + static LegoPfBitStreamEncoder bitStreamEncoder; + testStartBit(bitStreamEncoder); + testLowBit(bitStreamEncoder); + testHighBit(bitStreamEncoder); + testMessageBitCount(bitStreamEncoder); + testMessageBitCountRepeat(bitStreamEncoder); + testMessage407(bitStreamEncoder); + testMessage407Repeated(bitStreamEncoder); + testGetChannelId1(bitStreamEncoder); + testGetChannelId2(bitStreamEncoder); + testGetChannelId3(bitStreamEncoder); + testGetChannelId4(bitStreamEncoder); + testGetMessageLengthAllHigh(bitStreamEncoder); + testGetMessageLengthAllLow(bitStreamEncoder); +} + +void logTestResult(bool testPassed) { + if (testPassed) { + Serial.println("OK"); + } + else { + Serial.println("FAIL ############"); + } +} + +void testStartBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testStartBit "); + bitStreamEncoder.reset(0, false); + int startMark = bitStreamEncoder.getMarkDuration(); + int startPause = bitStreamEncoder.getPauseDuration(); + logTestResult(startMark == 158 && startPause == 1184-158); +} + +void testLowBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testLowBit "); + bitStreamEncoder.reset(0, false); + bitStreamEncoder.next(); + int lowMark = bitStreamEncoder.getMarkDuration(); + int lowPause = bitStreamEncoder.getPauseDuration(); + logTestResult(lowMark == 158 && lowPause == 421-158); +} + +void testHighBit(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testHighBit "); + bitStreamEncoder.reset(0xFFFF, false); + bitStreamEncoder.next(); + int highMark = bitStreamEncoder.getMarkDuration(); + int highPause = bitStreamEncoder.getPauseDuration(); + logTestResult(highMark == 158 && highPause == 711-158); +} + +void testMessageBitCount(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessageBitCount "); + bitStreamEncoder.reset(0xFFFF, false); + int bitCount = 1; + while (bitStreamEncoder.next()) { + bitCount++; + } + logTestResult(bitCount == 18); +} + +boolean check(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { + bool result = true; + result = result && bitStreamEncoder.getMarkDuration() == markDuration; + result = result && bitStreamEncoder.getPauseDuration() == pauseDuration; + return result; +} + +boolean checkNext(LegoPfBitStreamEncoder& bitStreamEncoder, unsigned long markDuration, unsigned long pauseDuration) { + bool result = bitStreamEncoder.next(); + result = result && check(bitStreamEncoder, markDuration, pauseDuration); + return result; +} + +boolean checkDataBitsOfMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { + bool result = true; + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 263); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + result = result && checkNext(bitStreamEncoder, 158, 553); + return result; +} + +void testMessage407(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessage407 "); + bitStreamEncoder.reset(407, false); + bool result = true; + result = result && check(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && !bitStreamEncoder.next(); + logTestResult(result); +} + +void testMessage407Repeated(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessage407Repeated "); + bitStreamEncoder.reset(407, true); + bool result = true; + result = result && check(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 5L * 16000L - 10844L); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026L + 8L * 16000L - 10844L); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && checkDataBitsOfMessage407(bitStreamEncoder); + result = result && checkNext(bitStreamEncoder, 158, 1026); + result = result && !bitStreamEncoder.next(); + logTestResult(result); +} + +void testMessageBitCountRepeat(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testMessageBitCountRepeat "); + bitStreamEncoder.reset(0xFFFF, true); + int bitCount = 1; + while (bitStreamEncoder.next()) { + bitCount++; + } + logTestResult(bitCount == 5*18); +} + +void testGetChannelId1(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId1 "); + bitStreamEncoder.reset(407, false); + logTestResult(bitStreamEncoder.getChannelId() == 1); +} + +void testGetChannelId2(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId2 "); + bitStreamEncoder.reset(4502, false); + logTestResult(bitStreamEncoder.getChannelId() == 2); +} + +void testGetChannelId3(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId3 "); + bitStreamEncoder.reset(8597, false); + logTestResult(bitStreamEncoder.getChannelId() == 3); +} + +void testGetChannelId4(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetChannelId4 "); + bitStreamEncoder.reset(12692, false); + logTestResult(bitStreamEncoder.getChannelId() == 4); +} + +void testGetMessageLengthAllHigh(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetMessageLengthAllHigh "); + bitStreamEncoder.reset(0xFFFF, false); + logTestResult(bitStreamEncoder.getMessageLength() == 13744); +} + +void testGetMessageLengthAllLow(LegoPfBitStreamEncoder& bitStreamEncoder) { + Serial.print(" testGetMessageLengthAllLow "); + bitStreamEncoder.reset(0x0, false); + logTestResult(bitStreamEncoder.getMessageLength() == 9104); +} diff --git a/Arduino_Code/Arduino-IRremote/irPronto.cpp b/Arduino_Code/Arduino-IRremote/irPronto.cpp new file mode 100644 index 000000000..0f530a900 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/irPronto.cpp @@ -0,0 +1,513 @@ +#define TEST 0 + +#if TEST +# define SEND_PRONTO 1 +# define PRONTO_ONCE false +# define PRONTO_REPEAT true +# define PRONTO_FALLBACK true +# define PRONTO_NOFALLBACK false +#endif + +#if SEND_PRONTO + +//****************************************************************************** +#if TEST +# include + void enableIROut (int freq) { printf("\nFreq = %d KHz\n", freq); } + void mark (int t) { printf("+%d," , t); } + void space (int t) { printf("-%d, ", t); } +#else +# include "IRremote.h" +#endif // TEST + +//+============================================================================= +// Check for a valid hex digit +// +bool ishex (char ch) +{ + return ( ((ch >= '0') && (ch <= '9')) || + ((ch >= 'A') && (ch <= 'F')) || + ((ch >= 'a') && (ch <= 'f')) ) ? true : false ; +} + +//+============================================================================= +// Check for a valid "blank" ... '\0' is a valid "blank" +// +bool isblank (char ch) +{ + return ((ch == ' ') || (ch == '\t') || (ch == '\0')) ? true : false ; +} + +//+============================================================================= +// Bypass spaces +// +bool byp (char** pcp) +{ + while (isblank(**pcp)) (*pcp)++ ; +} + +//+============================================================================= +// Hex-to-Byte : Decode a hex digit +// We assume the character has already been validated +// +uint8_t htob (char ch) +{ + if ((ch >= '0') && (ch <= '9')) return ch - '0' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; +} + +//+============================================================================= +// Hex-to-Word : Decode a block of 4 hex digits +// We assume the string has already been validated +// and the pointer being passed points at the start of a block of 4 hex digits +// +uint16_t htow (char* cp) +{ + return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; +} + +//+============================================================================= +// +bool sendPronto (char* s, bool repeat, bool fallback) +{ + int i; + int len; + int skip; + char* cp; + uint16_t freq; // Frequency in KHz + uint8_t usec; // pronto uSec/tick + uint8_t once; + uint8_t rpt; + + // Validate the string + for (cp = s; *cp; cp += 4) { + byp(&cp); + if ( !ishex(cp[0]) || !ishex(cp[1]) || + !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; + } + + // We will use cp to traverse the string + cp = s; + + // Check mode = Oscillated/Learned + byp(&cp); + if (htow(cp) != 0000) return false; + cp += 4; + + // Extract & set frequency + byp(&cp); + freq = (int)(1000000 / (htow(cp) * 0.241246)); // Rounding errors will occur, tolerance is +/- 10% + usec = (int)(((1.0 / freq) * 1000000) + 0.5); // Another rounding error, thank Cod for analogue electronics + freq /= 1000; // This will introduce a(nother) rounding error which we do not want in the usec calcualtion + cp += 4; + + // Get length of "once" code + byp(&cp); + once = htow(cp); + cp += 4; + + // Get length of "repeat" code + byp(&cp); + rpt = htow(cp); + cp += 4; + + // Which code are we sending? + if (fallback) { // fallback on the "other" code if "this" code is not present + if (!repeat) { // requested 'once' + if (once) len = once * 2, skip = 0 ; // if once exists send it + else len = rpt * 2, skip = 0 ; // else send repeat code + } else { // requested 'repeat' + if (rpt) len = rpt * 2, skip = 0 ; // if rpt exists send it + else len = once * 2, skip = 0 ; // else send once code + } + } else { // Send what we asked for, do not fallback if the code is empty! + if (!repeat) len = once * 2, skip = 0 ; // 'once' starts at 0 + else len = rpt * 2, skip = once ; // 'repeat' starts where 'once' ends + } + + // Skip to start of code + for (i = 0; i < skip; i++, cp += 4) byp(&cp) ; + + // Send code + enableIROut(freq); + for (i = 0; i < len; i++) { + byp(&cp); + if (i & 1) space(htow(cp) * usec); + else mark (htow(cp) * usec); + cp += 4; + } +} + +//+============================================================================= +#if TEST + +int main ( ) +{ + char prontoTest[] = + "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 + "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 + "0010 0030 0010 0aa6"; // 104 + + sendPronto(prontoTest, PRONTO_ONCE, PRONTO_FALLBACK); // once code + sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_FALLBACK); // repeat code + sendPronto(prontoTest, PRONTO_ONCE, PRONTO_NOFALLBACK); // once code + sendPronto(prontoTest, PRONTO_REPEAT, PRONTO_NOFALLBACK); // repeat code + + return 0; +} + +#endif // TEST + +#endif // SEND_PRONTO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#if 0 +//****************************************************************************** +// Sources: +// http://www.remotecentral.com/features/irdisp2.htm +// http://www.hifi-remote.com/wiki/index.php?title=Working_With_Pronto_Hex +//****************************************************************************** + +#include +#include + +#define IRPRONTO +#include "IRremoteInt.h" // The Arduino IRremote library defines USECPERTICK + +//------------------------------------------------------------------------------ +// Source: https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet +// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls +// +char prontoTest[] = + "0000 0070 0000 0032 0080 0040 0010 0010 0010 0030 " // 10 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 20 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 30 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 40 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 50 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0010 " // 60 + "0010 0010 0010 0010 0010 0010 0010 0010 0010 0010 " // 70 + "0010 0010 0010 0030 0010 0010 0010 0030 0010 0010 " // 80 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 90 + "0010 0010 0010 0030 0010 0010 0010 0010 0010 0030 " // 100 + "0010 0030 0010 0aa6"; // 104 + +//------------------------------------------------------------------------------ +// This is the longest code we can support +#define CODEMAX 200 + +//------------------------------------------------------------------------------ +// This is the data we pull out of the pronto code +typedef + struct { + int freq; // Carrier frequency (in Hz) + int usec; // uSec per tick (based on freq) + + int codeLen; // Length of code + uint16_t code[CODEMAX]; // Code in hex + + int onceLen; // Length of "once" transmit + uint16_t* once; // Pointer to start within 'code' + + int rptLen; // Length of "repeat" transmit + uint16_t* rpt; // Pointer to start within 'code' + } +pronto_t; + +//------------------------------------------------------------------------------ +// From what I have seen, the only time we go over 8-bits is the 'space' +// on the end which creates the lead-out/inter-code gap. Assuming I'm right, +// we can code this up as a special case and otherwise halve the size of our +// data! +// Ignoring the first four values (the config data) and the last value +// (the lead-out), if you find a protocol that uses values greater than 00fe +// we are going to have to revisit this code! +// +// +// So, the 0th byte will be the carrier frequency in Khz (NOT Hz) +// " 1st " " " " length of the "once" code +// " 2nd " " " " length of the "repeat" code +// +// Thereafter, odd bytes will be Mark lengths as a multiple of USECPERTICK uS +// even " " " Space " " " " " " " +// +// Any occurence of "FF" in either a Mark or a Space will indicate +// "Use the 16-bit FF value" which will also be a multiple of USECPERTICK uS +// +// +// As a point of comparison, the test code (prontoTest[]) is 520 bytes +// (yes, more than 0.5KB of our Arduino's precious 32KB) ... after conversion +// to pronto hex that goes down to ((520/5)*2) = 208 bytes ... once converted to +// our format we are down to ((208/2) -1 -1 +2) = 104 bytes +// +// In fariness this is still very memory-hungry +// ...As a rough guide: +// 10 codes cost 1K of memory (this will vary depending on the protocol). +// +// So if you're building a complex remote control, you will probably need to +// keep the codes on an external memory device (not in the Arduino sketch) and +// load them as you need them. Hmmm. +// +// This dictates that "Oscillated Pronto Codes" are probably NOT the way forward +// +// For example, prontoTest[] happens to be: A 48-bit IR code in Denon format +// So we know it starts with 80/40 (Denon header) +// and ends with 10/aa6 (Denon leadout) +// and all (48) bits in between are either 10/10 (Denon 0) +// or 10/30 (Denon 1) +// So we could easily store this data in 1-byte ("Denon") +// + 1-byte (Length=48) +// + 6-bytes (IR code) +// At 8-bytes per code, we can store 128 codes in 1KB or memory - that's a lot +// better than the 2 (two) we started off with! +// +// And serendipitously, by reducing the amount of data, our program will run +// a LOT faster! +// +// Again, I repeat, even after you have spent time converting the "Oscillated +// Pronto Codes" in to IRremote format, it will be a LOT more memory-hungry +// than using sendDenon() (or whichever) ...BUT these codes are easily +// available on the internet, so we'll support them! +// +typedef + struct { + uint16_t FF; + uint8_t code[CODEMAX]; + } +irCode_t; + +//------------------------------------------------------------------------------ +#define DEBUGF(...) printf(__VA_ARGS__) + +//+============================================================================= +// String must be block of 4 hex digits separated with blanks +// +bool validate (char* cp, int* len) +{ + for (*len = 0; *cp; (*len)++, cp += 4) { + byp(&cp); + if ( !ishex(cp[0]) || !ishex(cp[1]) || + !ishex(cp[2]) || !ishex(cp[3]) || !isblank(cp[4]) ) return false ; + } + + return true; +} + +//+============================================================================= +// Hex-to-Byte : Decode a hex digit +// We assume the character has already been validated +// +uint8_t htob (char ch) +{ + if ((ch >= '0') && (ch <= '9')) return ch - '0' ; + if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10 ; + if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10 ; +} + +//+============================================================================= +// Hex-to-Word : Decode a block of 4 hex digits +// We assume the string has already been validated +// and the pointer being passed points at the start of a block of 4 hex digits +// +uint16_t htow (char* cp) +{ + return ( (htob(cp[0]) << 12) | (htob(cp[1]) << 8) | + (htob(cp[2]) << 4) | (htob(cp[3]) ) ) ; +} + +//+============================================================================= +// Convert the pronto string in to data +// +bool decode (char* s, pronto_t* p, irCode_t* ir) +{ + int i, len; + char* cp; + + // Validate the Pronto string + if (!validate(s, &p->codeLen)) { + DEBUGF("Invalid pronto string\n"); + return false ; + } + DEBUGF("Found %d hex codes\n", p->codeLen); + + // Allocate memory to store the decoded string + //if (!(p->code = malloc(p->len))) { + // DEBUGF("Memory allocation failed\n"); + // return false ; + //} + + // Check in case our code is too long + if (p->codeLen > CODEMAX) { + DEBUGF("Code too long, edit CODEMAX and recompile\n"); + return false ; + } + + // Decode the string + cp = s; + for (i = 0; i < p->codeLen; i++, cp += 4) { + byp(&cp); + p->code[i] = htow(cp); + } + + // Announce our findings + DEBUGF("Input: |%s|\n", s); + DEBUGF("Found: |"); + for (i = 0; i < p->codeLen; i++) DEBUGF("%04x ", p->code[i]) ; + DEBUGF("|\n"); + + DEBUGF("Form [%04X] : ", p->code[0]); + if (p->code[0] == 0x0000) DEBUGF("Oscillated (Learned)\n"); + else if (p->code[0] == 0x0100) DEBUGF("Unmodulated\n"); + else DEBUGF("Unknown\n"); + if (p->code[0] != 0x0000) return false ; // Can only handle Oscillated + + // Calculate the carrier frequency (+/- 10%) & uSecs per pulse + // Pronto uses a crystal which generates a timeabse of 0.241246 + p->freq = (int)(1000000 / (p->code[1] * 0.241246)); + p->usec = (int)(((1.0 / p->freq) * 1000000) + 0.5); + ir->code[0] = p->freq / 1000; + DEBUGF("Freq [%04X] : %d Hz (%d uS/pluse) -> %d KHz\n", + p->code[1], p->freq, p->usec, ir->code[0]); + + // Set the length & start pointer for the "once" code + p->onceLen = p->code[2]; + p->once = &p->code[4]; + ir->code[1] = p->onceLen; + DEBUGF("Once [%04X] : %d\n", p->code[2], p->onceLen); + + // Set the length & start pointer for the "repeat" code + p->rptLen = p->code[3]; + p->rpt = &p->code[4 + p->onceLen]; + ir->code[2] = p->rptLen; + DEBUGF("Rpt [%04X] : %d\n", p->code[3], p->rptLen); + + // Check everything tallies + if (1 + 1 + 1 + 1 + (p->onceLen * 2) + (p->rptLen * 2) != p->codeLen) { + DEBUGF("Bad code length\n"); + return false; + } + + // Convert the IR data to our new format + ir->FF = p->code[p->codeLen - 1]; + + len = (p->onceLen * 2) + (p->rptLen * 2); + DEBUGF("Encoded: |"); + for (i = 0; i < len; i++) { + if (p->code[i+4] == ir->FF) { + ir->code[i+3] = 0xFF; + } else if (p->code[i+4] > 0xFE) { + DEBUGF("\n%04X : Mark/Space overflow\n", p->code[i+4]); + return false; + } else { + ir->code[i+3] = (p->code[i+4] * p->usec) / USECPERTICK; + } + DEBUGF("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); + } + DEBUGF("|\n"); + + ir->FF = (ir->FF * p->usec) / USECPERTICK; + DEBUGF("FF -> %d\n", ir->FF); + + return true; +} + +//+============================================================================= +// +void irDump (irCode_t* ir) +{ + int i, len; + + printf("uint8_t buttonName[%d] = {", len); + + printf("%d,%d, ", (ir->FF >> 8), ir->FF & 0xFF); + printf("%d,%d,%d, ", ir->code[0], ir->code[1], ir->code[2]); + + len = (ir->code[1] * 2) + (ir->code[2] * 2); + for (i = 0; i < len; i++) { + printf("%s%d", !i ? "" : (i&1 ? "," : ", "), ir->code[i+3]); + } + + printf("};\n"); + +} + +//+============================================================================= +// +int main ( ) +{ + pronto_t pCode; + irCode_t irCode; + + decode(prontoTest, &pCode, &irCode); + + irDump(&irCode); + + return 0; +} + +#endif //0 diff --git a/Arduino_Code/Arduino-IRremote/irRecv.cpp b/Arduino_Code/Arduino-IRremote/irRecv.cpp new file mode 100644 index 000000000..12b0806b1 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/irRecv.cpp @@ -0,0 +1,235 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +#ifdef IR_TIMER_USE_ESP32 +hw_timer_t *timer; +void IRTimer(); // defined in IRremote.cpp +#endif + +//+============================================================================= +// Decodes the received IR message +// Returns 0 if no data ready, 1 if data ready. +// Results of decoding are stored in results +// +int IRrecv::decode (decode_results *results) +{ + results->rawbuf = irparams.rawbuf; + results->rawlen = irparams.rawlen; + + results->overflow = irparams.overflow; + + if (irparams.rcvstate != STATE_STOP) return false ; + +#if DECODE_NEC + DBG_PRINTLN("Attempting NEC decode"); + if (decodeNEC(results)) return true ; +#endif + +#if DECODE_SONY + DBG_PRINTLN("Attempting Sony decode"); + if (decodeSony(results)) return true ; +#endif + +#if DECODE_SANYO + DBG_PRINTLN("Attempting Sanyo decode"); + if (decodeSanyo(results)) return true ; +#endif + +#if DECODE_MITSUBISHI + DBG_PRINTLN("Attempting Mitsubishi decode"); + if (decodeMitsubishi(results)) return true ; +#endif + +#if DECODE_RC5 + DBG_PRINTLN("Attempting RC5 decode"); + if (decodeRC5(results)) return true ; +#endif + +#if DECODE_RC6 + DBG_PRINTLN("Attempting RC6 decode"); + if (decodeRC6(results)) return true ; +#endif + +#if DECODE_PANASONIC + DBG_PRINTLN("Attempting Panasonic decode"); + if (decodePanasonic(results)) return true ; +#endif + +#if DECODE_LG + DBG_PRINTLN("Attempting LG decode"); + if (decodeLG(results)) return true ; +#endif + +#if DECODE_JVC + DBG_PRINTLN("Attempting JVC decode"); + if (decodeJVC(results)) return true ; +#endif + +#if DECODE_SAMSUNG + DBG_PRINTLN("Attempting SAMSUNG decode"); + if (decodeSAMSUNG(results)) return true ; +#endif + +#if DECODE_WHYNTER + DBG_PRINTLN("Attempting Whynter decode"); + if (decodeWhynter(results)) return true ; +#endif + +#if DECODE_AIWA_RC_T501 + DBG_PRINTLN("Attempting Aiwa RC-T501 decode"); + if (decodeAiwaRCT501(results)) return true ; +#endif + +#if DECODE_DENON + DBG_PRINTLN("Attempting Denon decode"); + if (decodeDenon(results)) return true ; +#endif + +#if DECODE_LEGO_PF + DBG_PRINTLN("Attempting Lego Power Functions"); + if (decodeLegoPowerFunctions(results)) return true ; +#endif + + // decodeHash returns a hash on any input. + // Thus, it needs to be last in the list. + // If you add any decodes, add them before this. + if (decodeHash(results)) return true ; + + // Throw away and start over + resume(); + return false; +} + +//+============================================================================= +IRrecv::IRrecv (int recvpin) +{ + irparams.recvpin = recvpin; + irparams.blinkflag = 0; +} + +IRrecv::IRrecv (int recvpin, int blinkpin) +{ + irparams.recvpin = recvpin; + irparams.blinkpin = blinkpin; + pinMode(blinkpin, OUTPUT); + irparams.blinkflag = 0; +} + + + +//+============================================================================= +// initialization +// +void IRrecv::enableIRIn ( ) +{ +// Interrupt Service Routine - Fires every 50uS +#ifdef ESP32 + // ESP32 has a proper API to setup timers, no weird chip macros needed + // simply call the readable API versions :) + // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up + timer = timerBegin(1, 80, 1); + timerAttachInterrupt(timer, &IRTimer, 1); + // every 50ns, autoreload = true + timerAlarmWrite(timer, 50, true); + timerAlarmEnable(timer); +#else + cli(); + // Setup pulse clock timer interrupt + // Prescale /8 (16M/8 = 0.5 microseconds per tick) + // Therefore, the timer interval can range from 0.5 to 128 microseconds + // Depending on the reset value (255 to 0) + TIMER_CONFIG_NORMAL(); + + // Timer2 Overflow Interrupt Enable + TIMER_ENABLE_INTR; + + TIMER_RESET; + + sei(); // enable interrupts +#endif + + // Initialize state machine variables + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; + + // Set pin modes + pinMode(irparams.recvpin, INPUT); +} + +//+============================================================================= +// Enable/disable blinking of pin 13 on IR processing +// +void IRrecv::blink13 (int blinkflag) +{ + irparams.blinkflag = blinkflag; + if (blinkflag) pinMode(BLINKLED, OUTPUT) ; +} + +//+============================================================================= +// Return if receiving new IR signals +// +bool IRrecv::isIdle ( ) +{ + return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false; +} +//+============================================================================= +// Restart the ISR state machine +// +void IRrecv::resume ( ) +{ + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; +} + +//+============================================================================= +// hashdecode - decode an arbitrary IR code. +// Instead of decoding using a standard encoding scheme +// (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. +// +// The algorithm: look at the sequence of MARK signals, and see if each one +// is shorter (0), the same length (1), or longer (2) than the previous. +// Do the same with the SPACE signals. Hash the resulting sequence of 0's, +// 1's, and 2's to a 32-bit value. This will give a unique value for each +// different code (probably), for most code systems. +// +// http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html +// +// Compare two tick values, returning 0 if newval is shorter, +// 1 if newval is equal, and 2 if newval is longer +// Use a tolerance of 20% +// +int IRrecv::compare (unsigned int oldval, unsigned int newval) +{ + if (newval < oldval * .8) return 0 ; + else if (oldval < newval * .8) return 2 ; + else return 1 ; +} + +//+============================================================================= +// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param +// Converts the raw code values into a 32-bit hash code. +// Hopefully this code is unique for each button. +// This isn't a "real" decoding, just an arbitrary value. +// +#define FNV_PRIME_32 16777619 +#define FNV_BASIS_32 2166136261 + +long IRrecv::decodeHash (decode_results *results) +{ + long hash = FNV_BASIS_32; + + // Require at least 6 samples to prevent triggering on noise + if (results->rawlen < 6) return false ; + + for (int i = 1; (i + 2) < results->rawlen; i++) { + int value = compare(results->rawbuf[i], results->rawbuf[i+2]); + // Add value into the hash + hash = (hash * FNV_PRIME_32) ^ value; + } + + results->value = hash; + results->bits = 32; + results->decode_type = UNKNOWN; + + return true; +} diff --git a/Arduino_Code/Arduino-IRremote/irSend.cpp b/Arduino_Code/Arduino-IRremote/irSend.cpp new file mode 100644 index 000000000..c3ef3ffac --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/irSend.cpp @@ -0,0 +1,90 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//+============================================================================= +void IRsend::sendRaw (const unsigned int buf[], unsigned int len, unsigned int hz) +{ + // Set IR carrier frequency + enableIROut(hz); + + for (unsigned int i = 0; i < len; i++) { + if (i & 1) space(buf[i]) ; + else mark (buf[i]) ; + } + + space(0); // Always end with the LED off +} + +//+============================================================================= +// Sends an IR mark for the specified number of microseconds. +// The mark output is modulated at the PWM frequency. +// +void IRsend::mark (unsigned int time) +{ + TIMER_ENABLE_PWM; // Enable pin 3 PWM output + if (time > 0) custom_delay_usec(time); +} + +//+============================================================================= +// Leave pin off for time (given in microseconds) +// Sends an IR space for the specified number of microseconds. +// A space is no output, so the PWM output is disabled. +// +void IRsend::space (unsigned int time) +{ + TIMER_DISABLE_PWM; // Disable pin 3 PWM output + if (time > 0) IRsend::custom_delay_usec(time); +} + + + + + +//+============================================================================= +// Enables IR output. The khz value controls the modulation frequency in kilohertz. +// The IR output will be on pin 3 (OC2B). +// This routine is designed for 36-40KHz; if you use it for other values, it's up to you +// to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) +// TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B +// controlling the duty cycle. +// There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) +// To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. +// A few hours staring at the ATmega documentation and this will all make sense. +// See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details. +// +void IRsend::enableIROut (int khz) +{ +// FIXME: implement ESP32 support, see IR_TIMER_USE_ESP32 in boarddefs.h +#ifndef ESP32 + // Disable the Timer2 Interrupt (which is used for receiving IR) + TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt + + pinMode(TIMER_PWM_PIN, OUTPUT); + digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low + + // COM2A = 00: disconnect OC2A + // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted + // WGM2 = 101: phase-correct PWM with OCRA as top + // CS2 = 000: no prescaling + // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. + TIMER_CONFIG_KHZ(khz); +#endif +} + +//+============================================================================= +// Custom delay function that circumvents Arduino's delayMicroseconds limit + +void IRsend::custom_delay_usec(unsigned long uSecs) { + if (uSecs > 4) { + unsigned long start = micros(); + unsigned long endMicros = start + uSecs - 4; + if (endMicros < start) { // Check if overflow + while ( micros() > start ) {} // wait until overflow + } + while ( micros() < endMicros ) {} // normal wait + } + //else { + // __asm__("nop\n\t"); // must have or compiler optimizes out + //} +} + diff --git a/Arduino_Code/Arduino-IRremote/ir_Aiwa.cpp b/Arduino_Code/Arduino-IRremote/ir_Aiwa.cpp new file mode 100644 index 000000000..50ec58d8c --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Aiwa.cpp @@ -0,0 +1,105 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// AAA IIIII W W AAA +// A A I W W A A +// AAAAA I W W W AAAAA +// A A I W W W A A +// A A IIIII WWW A A +//============================================================================== + +// Based off the RC-T501 RCU +// Lirc file http://lirc.sourceforge.net/remotes/aiwa/RC-T501 + +#define AIWA_RC_T501_HZ 38 +#define AIWA_RC_T501_BITS 15 +#define AIWA_RC_T501_PRE_BITS 26 +#define AIWA_RC_T501_POST_BITS 1 +#define AIWA_RC_T501_SUM_BITS (AIWA_RC_T501_PRE_BITS + AIWA_RC_T501_BITS + AIWA_RC_T501_POST_BITS) +#define AIWA_RC_T501_HDR_MARK 8800 +#define AIWA_RC_T501_HDR_SPACE 4500 +#define AIWA_RC_T501_BIT_MARK 500 +#define AIWA_RC_T501_ONE_SPACE 600 +#define AIWA_RC_T501_ZERO_SPACE 1700 + +//+============================================================================= +#if SEND_AIWA_RC_T501 +void IRsend::sendAiwaRCT501 (int code) +{ + unsigned long pre = 0x0227EEC0; // 26-bits + + // Set IR carrier frequency + enableIROut(AIWA_RC_T501_HZ); + + // Header + mark(AIWA_RC_T501_HDR_MARK); + space(AIWA_RC_T501_HDR_SPACE); + + // Send "pre" data + for (unsigned long mask = 1UL << (26 - 1); mask; mask >>= 1) { + mark(AIWA_RC_T501_BIT_MARK); + if (pre & mask) space(AIWA_RC_T501_ONE_SPACE) ; + else space(AIWA_RC_T501_ZERO_SPACE) ; + } + +//-v- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! +// it only send 15bits and ignores the top bit +// then uses TOPBIT which is 0x80000000 to check the bit code +// I suspect TOPBIT should be changed to 0x00008000 + + // Skip first code bit + code <<= 1; + // Send code + for (int i = 0; i < 15; i++) { + mark(AIWA_RC_T501_BIT_MARK); + if (code & 0x80000000) space(AIWA_RC_T501_ONE_SPACE) ; + else space(AIWA_RC_T501_ZERO_SPACE) ; + code <<= 1; + } + +//-^- THIS CODE LOOKS LIKE IT MIGHT BE WRONG - CHECK! + + // POST-DATA, 1 bit, 0x0 + mark(AIWA_RC_T501_BIT_MARK); + space(AIWA_RC_T501_ZERO_SPACE); + + mark(AIWA_RC_T501_BIT_MARK); + space(0); +} +#endif + +//+============================================================================= +#if DECODE_AIWA_RC_T501 +bool IRrecv::decodeAiwaRCT501 (decode_results *results) +{ + int data = 0; + int offset = 1; + + // Check SIZE + if (irparams.rawlen < 2 * (AIWA_RC_T501_SUM_BITS) + 4) return false ; + + // Check HDR Mark/Space + if (!MATCH_MARK (results->rawbuf[offset++], AIWA_RC_T501_HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], AIWA_RC_T501_HDR_SPACE)) return false ; + + offset += 26; // skip pre-data - optional + while(offset < irparams.rawlen - 4) { + if (MATCH_MARK(results->rawbuf[offset], AIWA_RC_T501_BIT_MARK)) offset++ ; + else return false ; + + // ONE & ZERO + if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], AIWA_RC_T501_ZERO_SPACE)) data = (data << 1) | 0 ; + else break ; // End of one & zero detected + offset++; + } + + results->bits = (offset - 1) / 2; + if (results->bits < 42) return false ; + + results->value = data; + results->decode_type = AIWA_RC_T501; + return true; +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Denon.cpp b/Arduino_Code/Arduino-IRremote/ir_Denon.cpp new file mode 100644 index 000000000..c54e28654 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Denon.cpp @@ -0,0 +1,94 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +// Reverse Engineered by looking at RAW dumps generated by IRremote + +// I have since discovered that Denon publish all their IR codes: +// https://www.google.co.uk/search?q=DENON+MASTER+IR+Hex+Command+Sheet +// -> http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls + +// Having looked at the official Denon Pronto sheet and reverse engineered +// the timing values from it, it is obvious that Denon have a range of +// different timings and protocols ...the values here work for my AVR-3801 Amp! + +//============================================================================== +// DDDD EEEEE N N OOO N N +// D D E NN N O O NN N +// D D EEE N N N O O N N N +// D D E N NN O O N NN +// DDDD EEEEE N N OOO N N +//============================================================================== + +#define BITS 14 // The number of bits in the command + +#define HDR_MARK 300 // The length of the Header:Mark +#define HDR_SPACE 750 // The lenght of the Header:Space + +#define BIT_MARK 300 // The length of a Bit:Mark +#define ONE_SPACE 1800 // The length of a Bit:Space for 1's +#define ZERO_SPACE 750 // The length of a Bit:Space for 0's + +//+============================================================================= +// +#if SEND_DENON +void IRsend::sendDenon (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark (HDR_MARK); + space(HDR_SPACE); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark (BIT_MARK); + space(ONE_SPACE); + } else { + mark (BIT_MARK); + space(ZERO_SPACE); + } + } + + // Footer + mark(BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +// +#if DECODE_DENON +bool IRrecv::decodeDenon (decode_results *results) +{ + unsigned long data = 0; // Somewhere to build our code + int offset = 1; // Skip the Gap reading + + // Check we have the right amount of data + if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; + + // Check initial Mark+Space match + if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; + + // Read the bits in + for (int i = 0; i < BITS; i++) { + // Each bit looks like: MARK + SPACE_1 -> 1 + // or : MARK + SPACE_0 -> 0 + if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; + + // IR data is big-endian, so we shuffle it in from the right: + if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = BITS; + results->value = data; + results->decode_type = DENON; + return true; +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Dish.cpp b/Arduino_Code/Arduino-IRremote/ir_Dish.cpp new file mode 100644 index 000000000..fa8e06516 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Dish.cpp @@ -0,0 +1,54 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// DDDD IIIII SSSS H H +// D D I S H H +// D D I SSS HHHHH +// D D I S H H +// DDDD IIIII SSSS H H +//============================================================================== + +// Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) +// +// The sned function needs to be repeated 4 times +// +// Only send the last for characters of the hex. +// I.E. Use 0x1C10 instead of 0x0000000000001C10 as listed in the LIRC file. +// +// Here is the LIRC file I found that seems to match the remote codes from the +// oscilloscope: +// DISH NETWORK (echostar 301): +// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx + +#define DISH_BITS 16 +#define DISH_HDR_MARK 400 +#define DISH_HDR_SPACE 6100 +#define DISH_BIT_MARK 400 +#define DISH_ONE_SPACE 1700 +#define DISH_ZERO_SPACE 2800 +#define DISH_RPT_SPACE 6200 + +//+============================================================================= +#if SEND_DISH +void IRsend::sendDISH (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(56); + + mark(DISH_HDR_MARK); + space(DISH_HDR_SPACE); + + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(DISH_BIT_MARK); + space(DISH_ONE_SPACE); + } else { + mark(DISH_BIT_MARK); + space(DISH_ZERO_SPACE); + } + } + mark(DISH_HDR_MARK); //added 26th March 2016, by AnalysIR ( https://www.AnalysIR.com ) +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_JVC.cpp b/Arduino_Code/Arduino-IRremote/ir_JVC.cpp new file mode 100644 index 000000000..eeec20fe9 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_JVC.cpp @@ -0,0 +1,101 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// JJJJJ V V CCCC +// J V V C +// J V V C +// J J V V C +// J V CCCC +//============================================================================== + +#define JVC_BITS 16 +#define JVC_HDR_MARK 8000 +#define JVC_HDR_SPACE 4000 +#define JVC_BIT_MARK 600 +#define JVC_ONE_SPACE 1600 +#define JVC_ZERO_SPACE 550 +#define JVC_RPT_LENGTH 60000 + +//+============================================================================= +// JVC does NOT repeat by sending a separate code (like NEC does). +// The JVC protocol repeats by skipping the header. +// To send a JVC repeat signal, send the original code value +// and set 'repeat' to true +// +#if SEND_JVC +void IRsend::sendJVC (unsigned long data, int nbits, bool repeat) +{ + // Set IR carrier frequency + enableIROut(38); + + // Only send the Header if this is NOT a repeat command + if (!repeat){ + mark(JVC_HDR_MARK); + space(JVC_HDR_SPACE); + } + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(JVC_BIT_MARK); + space(JVC_ONE_SPACE); + } else { + mark(JVC_BIT_MARK); + space(JVC_ZERO_SPACE); + } + } + + // Footer + mark(JVC_BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +#if DECODE_JVC +bool IRrecv::decodeJVC (decode_results *results) +{ + long data = 0; + int offset = 1; // Skip first space + + // Check for repeat + if ( (irparams.rawlen - 1 == 33) + && MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) + && MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK) + ) { + results->bits = 0; + results->value = REPEAT; + results->decode_type = JVC; + return true; + } + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset++], JVC_HDR_MARK)) return false ; + + if (irparams.rawlen < (2 * JVC_BITS) + 1 ) return false ; + + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset++], JVC_HDR_SPACE)) return false ; + + for (int i = 0; i < JVC_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset++], JVC_BIT_MARK)) return false ; + + if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Stop bit + if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) return false ; + + // Success + results->bits = JVC_BITS; + results->value = data; + results->decode_type = JVC; + + return true; +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_LG.cpp b/Arduino_Code/Arduino-IRremote/ir_LG.cpp new file mode 100644 index 000000000..ba532cb60 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_LG.cpp @@ -0,0 +1,80 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// L GGGG +// L G +// L G GG +// L G G +// LLLLL GGG +//============================================================================== + +#define LG_BITS 28 + +#define LG_HDR_MARK 8000 +#define LG_HDR_SPACE 4000 +#define LG_BIT_MARK 600 +#define LG_ONE_SPACE 1600 +#define LG_ZERO_SPACE 550 +#define LG_RPT_LENGTH 60000 + +//+============================================================================= +#if DECODE_LG +bool IRrecv::decodeLG (decode_results *results) +{ + long data = 0; + int offset = 1; // Skip first space + + // Check we have the right amount of data + if (irparams.rawlen < (2 * LG_BITS) + 1 ) return false ; + + // Initial mark/space + if (!MATCH_MARK(results->rawbuf[offset++], LG_HDR_MARK)) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], LG_HDR_SPACE)) return false ; + + for (int i = 0; i < LG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset++], LG_BIT_MARK)) return false ; + + if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Stop bit + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) return false ; + + // Success + results->bits = LG_BITS; + results->value = data; + results->decode_type = LG; + return true; +} +#endif + +//+============================================================================= +#if SEND_LG +void IRsend::sendLG (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark(LG_HDR_MARK); + space(LG_HDR_SPACE); + mark(LG_BIT_MARK); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + space(LG_ONE_SPACE); + mark(LG_BIT_MARK); + } else { + space(LG_ZERO_SPACE); + mark(LG_BIT_MARK); + } + } + space(0); // Always end with the LED off +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_Lego_PF.cpp b/Arduino_Code/Arduino-IRremote/ir_Lego_PF.cpp new file mode 100644 index 000000000..37d507ceb --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Lego_PF.cpp @@ -0,0 +1,46 @@ +#include "IRremote.h" +#include "IRremoteInt.h" +#include "ir_Lego_PF_BitStreamEncoder.h" + +//============================================================================== +// L EEEEEE EEEE OOOO +// L E E O O +// L EEEE E EEE O O +// L E E E O O LEGO Power Functions +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016 Philipp Henkel +//============================================================================== + +// Supported Devices +// LEGO® Power Functions IR Receiver 8884 + +//+============================================================================= +// +#if SEND_LEGO_PF + +#if DEBUG +namespace { +void logFunctionParameters(uint16_t data, bool repeat) { + DBG_PRINT("sendLegoPowerFunctions(data="); + DBG_PRINT(data); + DBG_PRINT(", repeat="); + DBG_PRINTLN(repeat?"true)" : "false)"); +} +} // anonymous namespace +#endif // DEBUG + +void IRsend::sendLegoPowerFunctions(uint16_t data, bool repeat) +{ +#if DEBUG + ::logFunctionParameters(data, repeat); +#endif // DEBUG + + enableIROut(38); + static LegoPfBitStreamEncoder bitStreamEncoder; + bitStreamEncoder.reset(data, repeat); + do { + mark(bitStreamEncoder.getMarkDuration()); + space(bitStreamEncoder.getPauseDuration()); + } while (bitStreamEncoder.next()); +} + +#endif // SEND_LEGO_PF diff --git a/Arduino_Code/Arduino-IRremote/ir_Lego_PF_BitStreamEncoder.h b/Arduino_Code/Arduino-IRremote/ir_Lego_PF_BitStreamEncoder.h new file mode 100644 index 000000000..e5a3d66a9 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Lego_PF_BitStreamEncoder.h @@ -0,0 +1,115 @@ + +//============================================================================== +// L EEEEEE EEEE OOOO +// L E E O O +// L EEEE E EEE O O +// L E E E O O LEGO Power Functions +// LLLLLL EEEEEE EEEE OOOO Copyright (c) 2016, 2017 Philipp Henkel +//============================================================================== + +//+============================================================================= +// + +class LegoPfBitStreamEncoder { + private: + uint16_t data; + bool repeatMessage; + uint8_t messageBitIdx; + uint8_t repeatCount; + uint16_t messageLength; + + public: + // HIGH data bit = IR mark + high pause + // LOW data bit = IR mark + low pause + static const uint16_t LOW_BIT_DURATION = 421; + static const uint16_t HIGH_BIT_DURATION = 711; + static const uint16_t START_BIT_DURATION = 1184; + static const uint16_t STOP_BIT_DURATION = 1184; + static const uint8_t IR_MARK_DURATION = 158; + static const uint16_t HIGH_PAUSE_DURATION = HIGH_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t LOW_PAUSE_DURATION = LOW_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t START_PAUSE_DURATION = START_BIT_DURATION - IR_MARK_DURATION; + static const uint16_t STOP_PAUSE_DURATION = STOP_BIT_DURATION - IR_MARK_DURATION; + static const uint8_t MESSAGE_BITS = 18; + static const uint16_t MAX_MESSAGE_LENGTH = 16000; + + void reset(uint16_t data, bool repeatMessage) { + this->data = data; + this->repeatMessage = repeatMessage; + messageBitIdx = 0; + repeatCount = 0; + messageLength = getMessageLength(); + } + + int getChannelId() const { return 1 + ((data >> 12) & 0x3); } + + uint16_t getMessageLength() const { + // Sum up all marks + uint16_t length = MESSAGE_BITS * IR_MARK_DURATION; + + // Sum up all pauses + length += START_PAUSE_DURATION; + for (unsigned long mask = 1UL << 15; mask; mask >>= 1) { + if (data & mask) { + length += HIGH_PAUSE_DURATION; + } else { + length += LOW_PAUSE_DURATION; + } + } + length += STOP_PAUSE_DURATION; + return length; + } + + boolean next() { + messageBitIdx++; + if (messageBitIdx >= MESSAGE_BITS) { + repeatCount++; + messageBitIdx = 0; + } + if (repeatCount >= 1 && !repeatMessage) { + return false; + } else if (repeatCount >= 5) { + return false; + } else { + return true; + } + } + + uint8_t getMarkDuration() const { return IR_MARK_DURATION; } + + uint32_t getPauseDuration() const { + if (messageBitIdx == 0) + return START_PAUSE_DURATION; + else if (messageBitIdx < MESSAGE_BITS - 1) { + return getDataBitPause(); + } else { + return getStopPause(); + } + } + + private: + uint16_t getDataBitPause() const { + const int pos = MESSAGE_BITS - 2 - messageBitIdx; + const bool isHigh = data & (1 << pos); + return isHigh ? HIGH_PAUSE_DURATION : LOW_PAUSE_DURATION; + } + + uint32_t getStopPause() const { + if (repeatMessage) { + return getRepeatStopPause(); + } else { + return STOP_PAUSE_DURATION; + } + } + + uint32_t getRepeatStopPause() const { + if (repeatCount == 0 || repeatCount == 1) { + return STOP_PAUSE_DURATION + (uint32_t)5 * MAX_MESSAGE_LENGTH - messageLength; + } else if (repeatCount == 2 || repeatCount == 3) { + return STOP_PAUSE_DURATION + + (uint32_t)(6 + 2 * getChannelId()) * MAX_MESSAGE_LENGTH - messageLength; + } else { + return STOP_PAUSE_DURATION; + } + } +}; diff --git a/Arduino_Code/Arduino-IRremote/ir_Mitsubishi.cpp b/Arduino_Code/Arduino-IRremote/ir_Mitsubishi.cpp new file mode 100644 index 000000000..7f83e530f --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Mitsubishi.cpp @@ -0,0 +1,85 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// MMMMM IIIII TTTTT SSSS U U BBBB IIIII SSSS H H IIIII +// M M M I T S U U B B I S H H I +// M M M I T SSS U U BBBB I SSS HHHHH I +// M M I T S U U B B I S H H I +// M M IIIII T SSSS UUU BBBBB IIIII SSSS H H IIIII +//============================================================================== + +// Looks like Sony except for timings, 48 chars of data and time/space different + +#define MITSUBISHI_BITS 16 + +// Mitsubishi RM 75501 +// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 +// #define MITSUBISHI_HDR_MARK 250 // seen range 3500 +#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 +#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 +#define MITSUBISHI_ZERO_MARK 750 // 17*50-100 +// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround +// #define MITSUBISHI_RPT_LENGTH 45000 + +//+============================================================================= +#if DECODE_MITSUBISHI +bool IRrecv::decodeMitsubishi (decode_results *results) +{ + // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); + long data = 0; + if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) return false ; + int offset = 0; // Skip first space + // Initial space + +#if 0 + // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); +#endif + +#if 0 + // Not seeing double keys from Mitsubishi + if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = MITSUBISHI; + return true; + } +#endif + + offset++; + + // Typical + // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 + + // Initial Space + if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) return false ; + offset++; + + while (offset + 1 < irparams.rawlen) { + if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) data = (data << 1) | 1 ; + else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) data <<= 1 ; + else return false ; + offset++; + + if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) break ; + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < MITSUBISHI_BITS) { + results->bits = 0; + return false; + } + + results->value = data; + results->decode_type = MITSUBISHI; + return true; +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_NEC.cpp b/Arduino_Code/Arduino-IRremote/ir_NEC.cpp new file mode 100644 index 000000000..3b4932100 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_NEC.cpp @@ -0,0 +1,98 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// N N EEEEE CCCC +// NN N E C +// N N N EEE C +// N NN E C +// N N EEEEE CCCC +//============================================================================== + +#define NEC_BITS 32 +#define NEC_HDR_MARK 9000 +#define NEC_HDR_SPACE 4500 +#define NEC_BIT_MARK 560 +#define NEC_ONE_SPACE 1690 +#define NEC_ZERO_SPACE 560 +#define NEC_RPT_SPACE 2250 + +//+============================================================================= +#if SEND_NEC +void IRsend::sendNEC (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark(NEC_HDR_MARK); + space(NEC_HDR_SPACE); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(NEC_BIT_MARK); + space(NEC_ONE_SPACE); + } else { + mark(NEC_BIT_MARK); + space(NEC_ZERO_SPACE); + } + } + + // Footer + mark(NEC_BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +// NECs have a repeat only 4 items long +// +#if DECODE_NEC +bool IRrecv::decodeNEC (decode_results *results) +{ + long data = 0; // We decode in to here; Start with nothing + int offset = 1; // Index in to results; Skip first entry!? + + // Check header "mark" + if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) return false ; + offset++; + + // Check for repeat + if ( (irparams.rawlen == 4) + && MATCH_SPACE(results->rawbuf[offset ], NEC_RPT_SPACE) + && MATCH_MARK (results->rawbuf[offset+1], NEC_BIT_MARK ) + ) { + results->bits = 0; + results->value = REPEAT; + results->decode_type = NEC; + return true; + } + + // Check we have enough data + if (irparams.rawlen < (2 * NEC_BITS) + 4) return false ; + + // Check header "space" + if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) return false ; + offset++; + + // Build the data + for (int i = 0; i < NEC_BITS; i++) { + // Check data "mark" + if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) return false ; + offset++; + // Suppend this bit + if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE )) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = NEC_BITS; + results->value = data; + results->decode_type = NEC; + + return true; +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Panasonic.cpp b/Arduino_Code/Arduino-IRremote/ir_Panasonic.cpp new file mode 100644 index 000000000..dc0dd7317 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Panasonic.cpp @@ -0,0 +1,78 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// PPPP AAA N N AAA SSSS OOO N N IIIII CCCC +// P P A A NN N A A S O O NN N I C +// PPPP AAAAA N N N AAAAA SSS O O N N N I C +// P A A N NN A A S O O N NN I C +// P A A N N A A SSSS OOO N N IIIII CCCC +//============================================================================== + +#define PANASONIC_BITS 48 +#define PANASONIC_HDR_MARK 3502 +#define PANASONIC_HDR_SPACE 1750 +#define PANASONIC_BIT_MARK 502 +#define PANASONIC_ONE_SPACE 1244 +#define PANASONIC_ZERO_SPACE 400 + +//+============================================================================= +#if SEND_PANASONIC +void IRsend::sendPanasonic (unsigned int address, unsigned long data) +{ + // Set IR carrier frequency + enableIROut(35); + + // Header + mark(PANASONIC_HDR_MARK); + space(PANASONIC_HDR_SPACE); + + // Address + for (unsigned long mask = 1UL << (16 - 1); mask; mask >>= 1) { + mark(PANASONIC_BIT_MARK); + if (address & mask) space(PANASONIC_ONE_SPACE) ; + else space(PANASONIC_ZERO_SPACE) ; + } + + // Data + for (unsigned long mask = 1UL << (32 - 1); mask; mask >>= 1) { + mark(PANASONIC_BIT_MARK); + if (data & mask) space(PANASONIC_ONE_SPACE) ; + else space(PANASONIC_ZERO_SPACE) ; + } + + // Footer + mark(PANASONIC_BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +#if DECODE_PANASONIC +bool IRrecv::decodePanasonic (decode_results *results) +{ + unsigned long long data = 0; + int offset = 1; + + if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_MARK )) return false ; + if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_HDR_SPACE)) return false ; + + // decode address + for (int i = 0; i < PANASONIC_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) return false ; + + if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE )) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + results->value = (unsigned long)data; + results->address = (unsigned int)(data >> 32); + results->decode_type = PANASONIC; + results->bits = PANASONIC_BITS; + + return true; +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_RC5_RC6.cpp b/Arduino_Code/Arduino-IRremote/ir_RC5_RC6.cpp new file mode 100644 index 000000000..10e79278e --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_RC5_RC6.cpp @@ -0,0 +1,207 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//+============================================================================= +// Gets one undecoded level at a time from the raw buffer. +// The RC5/6 decoding is easier if the data is broken into time intervals. +// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, +// successive calls to getRClevel will return MARK, MARK, SPACE. +// offset and used are updated to keep track of the current position. +// t1 is the time interval for a single bit in microseconds. +// Returns -1 for error (measured time interval is not a multiple of t1). +// +#if (DECODE_RC5 || DECODE_RC6) +int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1) +{ + int width; + int val; + int correction; + int avail; + + if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE. + width = results->rawbuf[*offset]; + val = ((*offset) % 2) ? MARK : SPACE; + correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS; + + if (MATCH(width, ( t1) + correction)) avail = 1 ; + else if (MATCH(width, (2*t1) + correction)) avail = 2 ; + else if (MATCH(width, (3*t1) + correction)) avail = 3 ; + else return -1 ; + + (*used)++; + if (*used >= avail) { + *used = 0; + (*offset)++; + } + + DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" ); + + return val; +} +#endif + +//============================================================================== +// RRRR CCCC 55555 +// R R C 5 +// RRRR C 5555 +// R R C 5 +// R R CCCC 5555 +// +// NB: First bit must be a one (start bit) +// +#define MIN_RC5_SAMPLES 11 +#define RC5_T1 889 +#define RC5_RPT_LENGTH 46000 + +//+============================================================================= +#if SEND_RC5 +void IRsend::sendRC5 (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(36); + + // Start + mark(RC5_T1); + space(RC5_T1); + mark(RC5_T1); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + space(RC5_T1); // 1 is space, then mark + mark(RC5_T1); + } else { + mark(RC5_T1); + space(RC5_T1); + } + } + + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +#if DECODE_RC5 +bool IRrecv::decodeRC5 (decode_results *results) +{ + int nbits; + long data = 0; + int used = 0; + int offset = 1; // Skip gap space + + if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ; + + // Get start bits + if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; + if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ; + if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ; + + for (nbits = 0; offset < irparams.rawlen; nbits++) { + int levelA = getRClevel(results, &offset, &used, RC5_T1); + int levelB = getRClevel(results, &offset, &used, RC5_T1); + + if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ; + else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ; + else return false ; + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = RC5; + return true; +} +#endif + +//+============================================================================= +// RRRR CCCC 6666 +// R R C 6 +// RRRR C 6666 +// R R C 6 6 +// R R CCCC 666 +// +// NB : Caller needs to take care of flipping the toggle bit +// +#define MIN_RC6_SAMPLES 1 +#define RC6_HDR_MARK 2666 +#define RC6_HDR_SPACE 889 +#define RC6_T1 444 +#define RC6_RPT_LENGTH 46000 + +#if SEND_RC6 +void IRsend::sendRC6 (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(36); + + // Header + mark(RC6_HDR_MARK); + space(RC6_HDR_SPACE); + + // Start bit + mark(RC6_T1); + space(RC6_T1); + + // Data + for (unsigned long i = 1, mask = 1UL << (nbits - 1); mask; i++, mask >>= 1) { + // The fourth bit we send is a "double width trailer bit" + int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ; + if (data & mask) { + mark(t); + space(t); + } else { + space(t); + mark(t); + } + } + + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +#if DECODE_RC6 +bool IRrecv::decodeRC6 (decode_results *results) +{ + int nbits; + long data = 0; + int used = 0; + int offset = 1; // Skip first space + + if (results->rawlen < MIN_RC6_SAMPLES) return false ; + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ; + + // Get start bit (1) + if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ; + if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ; + + for (nbits = 0; offset < results->rawlen; nbits++) { + int levelA, levelB; // Next two levels + + levelA = getRClevel(results, &offset, &used, RC6_T1); + if (nbits == 3) { + // T bit is double wide; make sure second half matches + if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false; + } + + levelB = getRClevel(results, &offset, &used, RC6_T1); + if (nbits == 3) { + // T bit is double wide; make sure second half matches + if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false; + } + + if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5 + else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ... + else return false ; // Error + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = RC6; + return true; +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Samsung.cpp b/Arduino_Code/Arduino-IRremote/ir_Samsung.cpp new file mode 100644 index 000000000..224487dbc --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Samsung.cpp @@ -0,0 +1,92 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// SSSS AAA MMM SSSS U U N N GGGG +// S A A M M M S U U NN N G +// SSS AAAAA M M M SSS U U N N N G GG +// S A A M M S U U N NN G G +// SSSS A A M M SSSS UUU N N GGG +//============================================================================== + +#define SAMSUNG_BITS 32 +#define SAMSUNG_HDR_MARK 5000 +#define SAMSUNG_HDR_SPACE 5000 +#define SAMSUNG_BIT_MARK 560 +#define SAMSUNG_ONE_SPACE 1600 +#define SAMSUNG_ZERO_SPACE 560 +#define SAMSUNG_RPT_SPACE 2250 + +//+============================================================================= +#if SEND_SAMSUNG +void IRsend::sendSAMSUNG (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark(SAMSUNG_HDR_MARK); + space(SAMSUNG_HDR_SPACE); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ONE_SPACE); + } else { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ZERO_SPACE); + } + } + + // Footer + mark(SAMSUNG_BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +// SAMSUNGs have a repeat only 4 items long +// +#if DECODE_SAMSUNG +bool IRrecv::decodeSAMSUNG (decode_results *results) +{ + long data = 0; + int offset = 1; // Skip first space + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) return false ; + offset++; + + // Check for repeat + if ( (irparams.rawlen == 4) + && MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE) + && MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK) + ) { + results->bits = 0; + results->value = REPEAT; + results->decode_type = SAMSUNG; + return true; + } + if (irparams.rawlen < (2 * SAMSUNG_BITS) + 4) return false ; + + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset++], SAMSUNG_HDR_SPACE)) return false ; + + for (int i = 0; i < SAMSUNG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset++], SAMSUNG_BIT_MARK)) return false ; + + if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = SAMSUNG_BITS; + results->value = data; + results->decode_type = SAMSUNG; + return true; +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_Sanyo.cpp b/Arduino_Code/Arduino-IRremote/ir_Sanyo.cpp new file mode 100644 index 000000000..c775d6118 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Sanyo.cpp @@ -0,0 +1,76 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// SSSS AAA N N Y Y OOO +// S A A NN N Y Y O O +// SSS AAAAA N N N Y O O +// S A A N NN Y O O +// SSSS A A N N Y OOO +//============================================================================== + +// I think this is a Sanyo decoder: Serial = SA 8650B +// Looks like Sony except for timings, 48 chars of data and time/space different + +#define SANYO_BITS 12 +#define SANYO_HDR_MARK 3500 // seen range 3500 +#define SANYO_HDR_SPACE 950 // seen 950 +#define SANYO_ONE_MARK 2400 // seen 2400 +#define SANYO_ZERO_MARK 700 // seen 700 +#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround +#define SANYO_RPT_LENGTH 45000 + +//+============================================================================= +#if DECODE_SANYO +bool IRrecv::decodeSanyo (decode_results *results) +{ + long data = 0; + int offset = 0; // Skip first space <-- CHECK THIS! + + if (irparams.rawlen < (2 * SANYO_BITS) + 2) return false ; + +#if 0 + // Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); +#endif + + // Initial space + if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) { + //Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = SANYO; + return true; + } + offset++; + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; + + // Skip Second Mark + if (!MATCH_MARK(results->rawbuf[offset++], SANYO_HDR_MARK)) return false ; + + while (offset + 1 < irparams.rawlen) { + if (!MATCH_SPACE(results->rawbuf[offset++], SANYO_HDR_SPACE)) break ; + + if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) data = (data << 1) | 1 ; + else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < 12) { + results->bits = 0; + return false; + } + + results->value = data; + results->decode_type = SANYO; + return true; +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Sharp.cpp b/Arduino_Code/Arduino-IRremote/ir_Sharp.cpp new file mode 100644 index 000000000..73462c5bc --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Sharp.cpp @@ -0,0 +1,71 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// SSSS H H AAA RRRR PPPP +// S H H A A R R P P +// SSS HHHHH AAAAA RRRR PPPP +// S H H A A R R P +// SSSS H H A A R R P +//============================================================================== + +// Sharp and DISH support by Todd Treece: http://unionbridge.org/design/ircommand +// +// The send function has the necessary repeat built in because of the need to +// invert the signal. +// +// Sharp protocol documentation: +// http://www.sbprojects.com/knowledge/ir/sharp.htm +// +// Here is the LIRC file I found that seems to match the remote codes from the +// oscilloscope: +// Sharp LCD TV: +// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA + +#define SHARP_BITS 15 +#define SHARP_BIT_MARK 245 +#define SHARP_ONE_SPACE 1805 +#define SHARP_ZERO_SPACE 795 +#define SHARP_GAP 600000 +#define SHARP_RPT_SPACE 3000 + +#define SHARP_TOGGLE_MASK 0x3FF + +//+============================================================================= +#if SEND_SHARP +void IRsend::sendSharpRaw (unsigned long data, int nbits) +{ + enableIROut(38); + + // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission + // much more reliable. That's the exact behaviour of CD-S6470 remote control. + for (int n = 0; n < 3; n++) { + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(SHARP_BIT_MARK); + space(SHARP_ONE_SPACE); + } else { + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + } + } + + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + delay(40); + + data = data ^ SHARP_TOGGLE_MASK; + } +} +#endif + +//+============================================================================= +// Sharp send compatible with data obtained through decodeSharp() +// ^^^^^^^^^^^^^ FUNCTION MISSING! +// +#if SEND_SHARP +void IRsend::sendSharp (unsigned int address, unsigned int command) +{ + sendSharpRaw((address << 10) | (command << 2) | 2, SHARP_BITS); +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Sony.cpp b/Arduino_Code/Arduino-IRremote/ir_Sony.cpp new file mode 100644 index 000000000..31e67cf78 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Sony.cpp @@ -0,0 +1,95 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// SSSS OOO N N Y Y +// S O O NN N Y Y +// SSS O O N N N Y +// S O O N NN Y +// SSSS OOO N N Y +//============================================================================== + +#define SONY_BITS 12 +#define SONY_HDR_MARK 2400 +#define SONY_HDR_SPACE 600 +#define SONY_ONE_MARK 1200 +#define SONY_ZERO_MARK 600 +#define SONY_RPT_LENGTH 45000 +#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround + +//+============================================================================= +#if SEND_SONY +void IRsend::sendSony (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(40); + + // Header + mark(SONY_HDR_MARK); + space(SONY_HDR_SPACE); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(SONY_ONE_MARK); + space(SONY_HDR_SPACE); + } else { + mark(SONY_ZERO_MARK); + space(SONY_HDR_SPACE); + } + } + + // We will have ended with LED off +} +#endif + +//+============================================================================= +#if DECODE_SONY +bool IRrecv::decodeSony (decode_results *results) +{ + long data = 0; + int offset = 0; // Dont skip first space, check its size + + if (irparams.rawlen < (2 * SONY_BITS) + 2) return false ; + + // Some Sony's deliver repeats fast after first + // unfortunately can't spot difference from of repeat from two fast clicks + if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + +# ifdef DECODE_SANYO + results->decode_type = SANYO; +# else + results->decode_type = UNKNOWN; +# endif + + return true; + } + offset++; + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset++], SONY_HDR_MARK)) return false ; + + while (offset + 1 < irparams.rawlen) { + if (!MATCH_SPACE(results->rawbuf[offset++], SONY_HDR_SPACE)) break ; + + if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) data = (data << 1) | 1 ; + else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < 12) { + results->bits = 0; + return false; + } + results->value = data; + results->decode_type = SONY; + return true; +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/ir_Template.cpp b/Arduino_Code/Arduino-IRremote/ir_Template.cpp new file mode 100644 index 000000000..eee2b0bb2 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Template.cpp @@ -0,0 +1,179 @@ +/* +Assuming the protocol we are adding is for the (imaginary) manufacturer: Shuzu + +Our fantasy protocol is a standard protocol, so we can use this standard +template without too much work. Some protocols are quite unique and will require +considerably more work in this file! It is way beyond the scope of this text to +explain how to reverse engineer "unusual" IR protocols. But, unless you own an +oscilloscope, the starting point is probably to use the rawDump.ino sketch and +try to spot the pattern! + +Before you start, make sure the IR library is working OK: + # Open up the Arduino IDE + # Load up the rawDump.ino example sketch + # Run it + +Now we can start to add our new protocol... + +1. Copy this file to : ir_Shuzu.cpp + +2. Replace all occurrences of "Shuzu" with the name of your protocol. + +3. Tweak the #defines to suit your protocol. + +4. If you're lucky, tweaking the #defines will make the default send() function + work. + +5. Again, if you're lucky, tweaking the #defines will have made the default + decode() function work. + +You have written the code to support your new protocol! + +Now you must do a few things to add it to the IRremote system: + +1. Open IRremote.h and make the following changes: + REMEMEBER to change occurences of "SHUZU" with the name of your protocol + + A. At the top, in the section "Supported Protocols", add: + #define DECODE_SHUZU 1 + #define SEND_SHUZU 1 + + B. In the section "enumerated list of all supported formats", add: + SHUZU, + to the end of the list (notice there is a comma after the protocol name) + + C. Further down in "Main class for receiving IR", add: + //...................................................................... + #if DECODE_SHUZU + bool decodeShuzu (decode_results *results) ; + #endif + + D. Further down in "Main class for sending IR", add: + //...................................................................... + #if SEND_SHUZU + void sendShuzu (unsigned long data, int nbits) ; + #endif + + E. Save your changes and close the file + +2. Now open irRecv.cpp and make the following change: + + A. In the function IRrecv::decode(), add: + #ifdef DECODE_NEC + DBG_PRINTLN("Attempting Shuzu decode"); + if (decodeShuzu(results)) return true ; + #endif + + B. Save your changes and close the file + +You will probably want to add your new protocol to the example sketch + +3. Open MyDocuments\Arduino\libraries\IRremote\examples\IRrecvDumpV2.ino + + A. In the encoding() function, add: + case SHUZU: Serial.print("SHUZU"); break ; + +Now open the Arduino IDE, load up the rawDump.ino sketch, and run it. +Hopefully it will compile and upload. +If it doesn't, you've done something wrong. Check your work. +If you can't get it to work - seek help from somewhere. + +If you get this far, I will assume you have successfully added your new protocol +There is one last thing to do. + +1. Delete this giant instructional comment. + +2. Send a copy of your work to us so we can include it in the library and + others may benefit from your hard work and maybe even write a song about how + great you are for helping them! :) + +Regards, + BlueChip +*/ + +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// +// +// S H U Z U +// +// +//============================================================================== + +#define BITS 32 // The number of bits in the command + +#define HDR_MARK 1000 // The length of the Header:Mark +#define HDR_SPACE 2000 // The lenght of the Header:Space + +#define BIT_MARK 3000 // The length of a Bit:Mark +#define ONE_SPACE 4000 // The length of a Bit:Space for 1's +#define ZERO_SPACE 5000 // The length of a Bit:Space for 0's + +#define OTHER 1234 // Other things you may need to define + +//+============================================================================= +// +#if SEND_SHUZU +void IRsend::sendShuzu (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Header + mark (HDR_MARK); + space(HDR_SPACE); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark (BIT_MARK); + space(ONE_SPACE); + } else { + mark (BIT_MARK); + space(ZERO_SPACE); + } + } + + // Footer + mark(BIT_MARK); + space(0); // Always end with the LED off +} +#endif + +//+============================================================================= +// +#if DECODE_SHUZU +bool IRrecv::decodeShuzu (decode_results *results) +{ + unsigned long data = 0; // Somewhere to build our code + int offset = 1; // Skip the Gap reading + + // Check we have the right amount of data + if (irparams.rawlen != 1 + 2 + (2 * BITS) + 1) return false ; + + // Check initial Mark+Space match + if (!MATCH_MARK (results->rawbuf[offset++], HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], HDR_SPACE)) return false ; + + // Read the bits in + for (int i = 0; i < SHUZU_BITS; i++) { + // Each bit looks like: MARK + SPACE_1 -> 1 + // or : MARK + SPACE_0 -> 0 + if (!MATCH_MARK(results->rawbuf[offset++], BIT_MARK)) return false ; + + // IR data is big-endian, so we shuffle it in from the right: + if (MATCH_SPACE(results->rawbuf[offset], ONE_SPACE)) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // Success + results->bits = BITS; + results->value = data; + results->decode_type = SHUZU; + return true; +} +#endif diff --git a/Arduino_Code/Arduino-IRremote/ir_Whynter.cpp b/Arduino_Code/Arduino-IRremote/ir_Whynter.cpp new file mode 100644 index 000000000..a830562c6 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/ir_Whynter.cpp @@ -0,0 +1,91 @@ +#include "IRremote.h" +#include "IRremoteInt.h" + +//============================================================================== +// W W H H Y Y N N TTTTT EEEEE RRRRR +// W W H H Y Y NN N T E R R +// W W W HHHHH Y N N N T EEE RRRR +// W W W H H Y N NN T E R R +// WWW H H Y N N T EEEEE R R +//============================================================================== + +#define WHYNTER_BITS 32 +#define WHYNTER_HDR_MARK 2850 +#define WHYNTER_HDR_SPACE 2850 +#define WHYNTER_BIT_MARK 750 +#define WHYNTER_ONE_MARK 750 +#define WHYNTER_ONE_SPACE 2150 +#define WHYNTER_ZERO_MARK 750 +#define WHYNTER_ZERO_SPACE 750 + +//+============================================================================= +#if SEND_WHYNTER +void IRsend::sendWhynter (unsigned long data, int nbits) +{ + // Set IR carrier frequency + enableIROut(38); + + // Start + mark(WHYNTER_ZERO_MARK); + space(WHYNTER_ZERO_SPACE); + + // Header + mark(WHYNTER_HDR_MARK); + space(WHYNTER_HDR_SPACE); + + // Data + for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) { + if (data & mask) { + mark(WHYNTER_ONE_MARK); + space(WHYNTER_ONE_SPACE); + } else { + mark(WHYNTER_ZERO_MARK); + space(WHYNTER_ZERO_SPACE); + } + } + + // Footer + mark(WHYNTER_ZERO_MARK); + space(WHYNTER_ZERO_SPACE); // Always end with the LED off +} +#endif + +//+============================================================================= +#if DECODE_WHYNTER +bool IRrecv::decodeWhynter (decode_results *results) +{ + long data = 0; + int offset = 1; // skip initial space + + // Check we have the right amount of data + if (irparams.rawlen < (2 * WHYNTER_BITS) + 6) return false ; + + // Sequence begins with a bit mark and a zero space + if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_BIT_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_ZERO_SPACE)) return false ; + + // header mark and space + if (!MATCH_MARK (results->rawbuf[offset++], WHYNTER_HDR_MARK )) return false ; + if (!MATCH_SPACE(results->rawbuf[offset++], WHYNTER_HDR_SPACE)) return false ; + + // data bits + for (int i = 0; i < WHYNTER_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset++], WHYNTER_BIT_MARK)) return false ; + + if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ONE_SPACE )) data = (data << 1) | 1 ; + else if (MATCH_SPACE(results->rawbuf[offset], WHYNTER_ZERO_SPACE)) data = (data << 1) | 0 ; + else return false ; + offset++; + } + + // trailing mark + if (!MATCH_MARK(results->rawbuf[offset], WHYNTER_BIT_MARK)) return false ; + + // Success + results->bits = WHYNTER_BITS; + results->value = data; + results->decode_type = WHYNTER; + return true; +} +#endif + diff --git a/Arduino_Code/Arduino-IRremote/keywords.txt b/Arduino_Code/Arduino-IRremote/keywords.txt new file mode 100644 index 000000000..f2b9a4957 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/keywords.txt @@ -0,0 +1,53 @@ +####################################### +# Syntax Coloring Map For IRremote +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +decode_results KEYWORD1 +IRrecv KEYWORD1 +IRsend KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +blink13 KEYWORD2 +decode KEYWORD2 +enableIRIn KEYWORD2 +resume KEYWORD2 +enableIROut KEYWORD2 +sendNEC KEYWORD2 +sendSony KEYWORD2 +sendSanyo KEYWORD2 +sendMitsubishi KEYWORD2 +sendRaw KEYWORD2 +sendRC5 KEYWORD2 +sendRC6 KEYWORD2 +sendDISH KEYWORD2 +sendSharp KEYWORD2 +sendSharpRaw KEYWORD2 +sendPanasonic KEYWORD2 +sendJVC KEYWORD2 +sendLG KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +NEC LITERAL1 +SONY LITERAL1 +SANYO LITERAL1 +MITSUBISHI LITERAL1 +RC5 LITERAL1 +RC6 LITERAL1 +DISH LITERAL1 +SHARP LITERAL1 +PANASONIC LITERAL1 +JVC LITERAL1 +LG LITERAL1 +AIWA_RC_T501 LITERAL1 +UNKNOWN LITERAL1 +REPEAT LITERAL1 diff --git a/Arduino_Code/Arduino-IRremote/library.json b/Arduino_Code/Arduino-IRremote/library.json new file mode 100644 index 000000000..d8cd523a7 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/library.json @@ -0,0 +1,24 @@ +{ + "name": "IRremote", + "keywords": "infrared, ir, remote", + "description": "Send and receive infrared signals with multiple protocols", + "repository": + { + "type": "git", + "url": "https://github.com/z3t0/Arduino-IRremote.git" + }, + "version": "2.3.3", + "frameworks": "arduino", + "platforms": "atmelavr", + "authors" : + [ + { + "name":"Rafi Khan", + "email":"zetoslab@gmail.com" + }, + { + "name":"Ken Shirriff", + "email":"ken.shirriff@gmail.com" + } + ] +} diff --git a/Arduino_Code/Arduino-IRremote/library.properties.txt b/Arduino_Code/Arduino-IRremote/library.properties.txt new file mode 100644 index 000000000..39fd814eb --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/library.properties.txt @@ -0,0 +1,9 @@ +name=IRremote +version=2.2.3 +author=shirriff +maintainer=shirriff +sentence=Send and receive infrared signals with multiple protocols +paragraph=Send and receive infrared signals with multiple protocols +category=Signal Input/Output +url=https://github.com/shirriff/Arduino-IRremote.git +architectures=* diff --git a/Arduino_Code/Arduino-IRremote/readmdFrench.md b/Arduino_Code/Arduino-IRremote/readmdFrench.md new file mode 100644 index 000000000..e531e9442 --- /dev/null +++ b/Arduino_Code/Arduino-IRremote/readmdFrench.md @@ -0,0 +1,97 @@ +## IRremote Library + + +Cette bibliothèque vous permet d'envoyer et de recevoir des signaux infrarouges sur un Arduino. +Des tutoriels et plus d'informations seront disponibles sur la page d'accueil officielle. + +## Version - 2.2.3 + +## Installation +1. Allez à la [Releases](https://github.com/z3t0/Arduino-IRremote/releases) page. +2. Téléchargez la dernière version. +3. Extraire le fichier zip +4. Déplacez le dossier "IRremote" vers vos bibliothèques. +5. Assurez-vous de supprimer Arduino_Root / libraries / RobotIRremote. Où Arduino_Root fait référence au répertoire d'installation d'Arduino. La bibliothèque RobotIRremote a des définitions similaires à IRremote et provoque des erreurs. + + +## FAQ +Je ne travaille pas correctement en utilisant Neopixels (aka WS2811 / WS2812 / WS2812B) +Que vous utilisiez la librairie Adafruit Neopixel ou FastLED, les interruptions sont désactivées sur de nombreux processeurs bas de gamme comme les arduinos de base. À son tour, cela empêche le gestionnaire IR de s'exécuter quand il le faut. Il y a quelques solutions à ce processus, voir cette page de Marc MERLIN +[cette page de Marc MERLIN](http://marc.merlins.org/perso/arduino/post_2017-04-03_Arduino-328P-Uno-Teensy3_1-ESP8266-ESP32-IR-and-Neopixels.html) + + +## Conseils pris en charge + +- Teensy 1.0 / 1.0++ / 2.0 / 2++ / 3.0 / 3.1 / Teensy-LC; Crédits: @PaulStoffregen (Teensy Team) +- Sanguino +- ATmega8, 48, 88, 168, 328 +- ATmega8535, 16, 32, 164, 324, 644, 1284, +- ATmega64, 128 +- ATtiny 84 / 85 +- ESP32 (recevoir seulement) +- ESP8266 est basé sur un ancien code qui n'est pas très récent, mais cela fonctionne raisonnablement bien. Voir https://github.com/markszabo/IRremoteESP8266 +Sparkfun Pro Micro + + + + +Nous sommes ouverts aux suggestions d'ajout de support pour les nouveaux tableaux, cependant, nous vous recommandons fortement de contacter votre fournisseur et de fournir un soutien de leur côté. + + +## Spécifications matérielles + + +| Carte/CPU | Envoyer Pin | Compteurs | +|--------------------------------------------------------------------------|---------------------|-------------------| +| [ATtiny84](https://github.com/SpenceKonde/ATTinyCore) | **6** | **1** | +| [ATtiny85](https://github.com/SpenceKonde/ATTinyCore) | **1** | **TINY0** | +| [ATmega8](https://github.com/MCUdude/MiniCore) | **9** | **1** | +| Atmega32u4 | 5, 9, **13** | 1, 3, **4** | +| [ATmega48, ATmega88, ATmega168, ATmega328](https://github.com/MCUdude/MiniCore) | **3**, 9 | 1, **2** | +| [ATmega1284](https://github.com/MCUdude/MightyCore) | 13, 14, 6 | 1, **2**, 3 | +| [ATmega164, ATmega324, ATmega644](https://github.com/MCUdude/MightyCore) | 13, **14** | 1, **2** | +| [ATmega8535 ATmega16, ATmega32](https://github.com/MCUdude/MightyCore) | **13** | **1** | +| [ATmega64, ATmega128](https://github.com/MCUdude/MegaCore) | **13** | **1** | +| ATmega1280, ATmega2560 | 5, 6, **9**, 11, 46 | 1, **2**, 3, 4, 5 | +| [ESP32](http://esp32.net/) | N/A (insupporté) | **1** | +| [Sparkfun Pro Micro](https://www.sparkfun.com/products/12640) | 9, **5**, 5 | 1, **3**, 4_HS | +| [Teensy 1.0](https://www.pjrc.com/teensy/) | **17** | **1** | +| [Teensy 2.0](https://www.pjrc.com/teensy/) | 9, **10**, 14 | 1, 3, **4_HS** | +| [Teensy++ 1.0 / 2.0](https://www.pjrc.com/teensy/) | **1**, 16, 25 | 1, **2**, 3 | +| [Teensy 3.0 / 3.1](https://www.pjrc.com/teensy/) | **5** | **CMT** | +| [Teensy-LC](https://www.pjrc.com/teensy/) | **16** | **TPM1** | + + +## Patchs expérimentaux + +Voici les correctifs strictement pris en charge qui n'ont pas encore été intégrés. Si vous avez des questions, n'hésitez pas à demander ici. Si cela fonctionne, faites le nous savoir! + +[Arduino 101](https://github.com/z3t0/Arduino-IRremote/pull/481#issuecomment-311243146) + +Le tableau ci-dessus répertorie les temporisations actuellement supportées et les broches d'envoi correspondantes, beaucoup de ces broches supplémentaires sont ouvertes. + + +## Utilisation +- À faire TODO (Vérifier les exemples pour l'instant) + + +## Contribution +Si vous voulez contribuer à ce projet: +- Signaler les bogues et les erreurs +- Demander des améliorations +- Créer des problèmes et tirer des requêtes +- Parlez de cette bibliothèque à d'autres personnes +- Contribuer de nouveaux protocoles +Vérifiez ici [ici](Contributing.md) pour quelques guidelines + + +## Contact +Email: zetoslab@gmail.com +Please only email me if it is more appropriate than creating an Issue / PR. I **will** not respond to requests for adding support for particular boards, unless of course you are the creator of the board and would like to cooperate on the project. I will also **ignore** any emails asking me to tell you how to implement your ideas. However, if you have a private inquiry that you would only apply to you and you would prefer it to be via email, by all means. + +## Contributeurs +Check [here](Contributors.md) +@Lsuperman735 French translation + +## Copyright +Copyright 2009-2012 Ken Shirriff diff --git a/Arduino_Code/Blink without delay b/Arduino_Code/Blink without delay new file mode 100644 index 000000000..c96f3baed --- /dev/null +++ b/Arduino_Code/Blink without delay @@ -0,0 +1,71 @@ +/* + Blink without Delay + + Turns on and off a light emitting diode (LED) connected to a digital pin, + without using the delay() function. This means that other code can run at the + same time without being interrupted by the LED code. + + The circuit: + - Use the onboard LED. + - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA + and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN + is set to the correct LED pin independent of which board is used. + If you want to know what pin the on-board LED is connected to on your + Arduino model, check the Technical Specs of your board at: + https://www.arduino.cc/en/Main/Products + + created 2005 + by David A. Mellis + modified 8 Feb 2010 + by Paul Stoffregen + modified 11 Nov 2013 + by Scott Fitzgerald + modified 9 Jan 2017 + by Arturo Guadalupi + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay +*/ + +// constants won't change. Used here to set a pin number: +const int ledPin = LED_BUILTIN;// the number of the LED pin + +// Variables will change: +int ledState = LOW; // ledState used to set the LED + +// Generally, you should use "unsigned long" for variables that hold time +// The value will quickly become too large for an int to store +unsigned long previousMillis = 0; // will store last time LED was updated + +// constants won't change: +const long interval = 1000; // interval at which to blink (milliseconds) + +void setup() { + // set the digital pin as output: + pinMode(ledPin, OUTPUT); +} + +void loop() { + // here is where you'd put code that needs to be running all the time. + + // check to see if it's time to blink the LED; that is, if the difference + // between the current time and last time you blinked the LED is bigger than + // the interval at which you want to blink the LED. + unsigned long currentMillis = millis(); + + if (currentMillis - previousMillis >= interval) { + // save the last time you blinked the LED + previousMillis = currentMillis; + + // if the LED is off turn it on and vice-versa: + if (ledState == LOW) { + ledState = HIGH; + } else { + ledState = LOW; + } + + // set the LED with the ledState of the variable: + digitalWrite(ledPin, ledState); + } +} diff --git a/Arduino_Code/EMF_Detector_upd.ino b/Arduino_Code/EMF_Detector_upd.ino new file mode 100644 index 000000000..2fa33ee46 --- /dev/null +++ b/Arduino_Code/EMF_Detector_upd.ino @@ -0,0 +1,40 @@ +/*This project measures the EMF intensity around any ac electrical appliances by LED + * this project is one of the simplest one that you can try. + * Before attempting the project get some idea about constrain() and map() functions in arduino math + * the fritzing sketch regarding the project can be found in Arduino101 repository + - Abhyuday */ + + + + + + +int antPin = 7; // antenna Pin to analog 7 +int analogValue = 0; // store small analog voltage values to analogValue and initialise it to 0 +int LED = 11; // Detection LED to A11 + +void setup() { + + Serial.begin(9600); // Beginning Serial Connection at 9600 Baud + +} + +void loop() { + + analogValue = analogRead(antPin); //Read analog values from antPin and assign them to analogValue + + if(analogValue >= 1) //if antPin sense analog wave in environment + { + + analogValue = constrain(val, 1, 100); //ranging the analogValue in (1 to 100)scale + analogValue = map(analogValue, 1, 100, 1, 255); //remapping analogValue in (1 to 255) scale + analogWrite(LED, analogValue); // HIGH the LED according to intensity of analogValue + }else{ + + analogWrite(LED, 0); //if antPin sense nothing then put LED at LOW + + } + + Serial.println(analogValue); + +} diff --git a/Arduino_Code/HC-SR04_ping.ino b/Arduino_Code/HC-SR04_ping.ino new file mode 100644 index 000000000..24de448fd --- /dev/null +++ b/Arduino_Code/HC-SR04_ping.ino @@ -0,0 +1,40 @@ + + +/*Before attempting the project try to get some knowledge +about the HC-SR04 Ultrasound Sensor and Arduino. + Abhyuday Tripathi */ + + + + + +long duration; // defining variables for time taken by the wave to comeback after emission. + +float distance;// defining variable for distance that has to be measured by the sensor. +int triggerPin = 13; +int echoPin = 11; + +void setup() { +pinMode(triggerPin, OUTPUT);//initialising triggerPin as OUTPUT. + +pinMode(echoPin, INPUT); //initialising echoPin as INPUT. + +Serial.begin(9600); //Activating the Serial at 9600 baud. +} + +void loop() { + digitalWrite(triggerPin, LOW); //triggerPin at LOW initially. + + delayMicroseconds(2); + + digitalWrite(triggerPin, HIGH);// Activating triggerPin to HIGH to generate 8-bit pulse for 10 microseconds. + delayMicroseconds(10); + + duration = pulseIn(echoPin, HIGH);// echoPin will be high untill no returning wave has hit it + // that is the duration which is required fo the calculation. + + distance = duration*0.03356*0.5 ; //calculating distance in centmeters. +Serial.print("Distance in cm : ");//Serial Monitor will print the distance with interval of one second. +Serial.println(distance); +delay(1000); +} diff --git a/Arduino_Code/Knock Sensor b/Arduino_Code/Knock Sensor new file mode 100644 index 000000000..99b50e4de --- /dev/null +++ b/Arduino_Code/Knock Sensor @@ -0,0 +1,54 @@ +/* + Knock Sensor + + This sketch reads a piezo element to detect a knocking sound. + It reads an analog pin and compares the result to a set threshold. + If the result is greater than the threshold, it writes "knock" to the serial + port, and toggles the LED on pin 13. + + The circuit: + - positive connection of the piezo attached to analog in 0 + - negative connection of the piezo attached to ground + - 1 megohm resistor attached from analog in 0 to ground + + created 25 Mar 2007 + by David Cuartielles + modified 30 Aug 2011 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/Knock +*/ + + +// these constants won't change: +const int ledPin = 13; // LED connected to digital pin 13 +const int knockSensor = A0; // the piezo is connected to analog pin 0 +const int threshold = 100; // threshold value to decide when the detected sound is a knock or not + + +// these variables will change: +int sensorReading = 0; // variable to store the value read from the sensor pin +int ledState = LOW; // variable used to store the last LED status, to toggle the light + +void setup() { + pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT + Serial.begin(9600); // use the serial port +} + +void loop() { + // read the sensor and store it in the variable sensorReading: + sensorReading = analogRead(knockSensor); + + // if the sensor reading is greater than the threshold: + if (sensorReading >= threshold) { + // toggle the status of the ledPin: + ledState = !ledState; + // update the LED pin itself: + digitalWrite(ledPin, ledState); + // send the string "Knock!" back to the computer, followed by newline + Serial.println("Knock!"); + } + delay(100); // delay to avoid overloading the serial port buffer +} diff --git a/Arduino_Code/Tachometer_upd.ino b/Arduino_Code/Tachometer_upd.ino new file mode 100644 index 000000000..2838db16d --- /dev/null +++ b/Arduino_Code/Tachometer_upd.ino @@ -0,0 +1,33 @@ +/* This Arduino Project Calculates RPM of any DC Wheeled Motor +Before attempting this project try to get some knowledge about +IR Proximity Sensor module. For this project you will need a dc motor +and wheel with **half black and half white** template on the wheel rim. +Main concept of IR Tachometer is transmission and reflection of IR signal. + Abhyuday Tripathi*/ + + + + + + + +long t ; //declaring global vaiable for time to complete half rotation. +const int out = 7; //IR OUT is set to digital Pin 7. +float rpm; //declaring RPM + +void setup() +{ + pinMode(out, INPUT); //initialising OUT as INPUT. + + Serial.begin(9600); //Activating Serial Connection at 9600 baud. + } + +void loop() { + t = pulseIn(out, LOW);// calculating time for which out stays LOW. + + rpm = 60000*0.5*1000/t ; //calculating RPM by keeping in mind that default time unit in Arduino is in Microseconds. + + Serial.print("RPM : "); //Printing results on the Serial Monitor with interval of 1 second. + Serial.println(rpm); +delay(1000); +} diff --git a/Arduino_Code/Voice_Control_BT.ino b/Arduino_Code/Voice_Control_BT.ino new file mode 100644 index 000000000..3e2cba98e --- /dev/null +++ b/Arduino_Code/Voice_Control_BT.ino @@ -0,0 +1,64 @@ +//Credit to: Angelo Casimiro + + + +String voice; +int +led1 = 2, //Connect LED 1 To Pin #2 +led2 = 3, //Connect LED 2 To Pin #3 +led3 = 4, //Connect LED 3 To Pin #4 +led4 = 5, //Connect LED 4 To Pin #5 +led5 = 6; //Connect LED 5 To Pin #6 +//--------------------------Call A Function-------------------------------// +void allon(){ + digitalWrite(led1, HIGH); + digitalWrite(led2, HIGH); + digitalWrite(led3, HIGH); + digitalWrite(led4, HIGH); + digitalWrite(led5, HIGH); +} +void alloff(){ + digitalWrite(led1, LOW); + digitalWrite(led2, LOW); + digitalWrite(led3, LOW); + digitalWrite(led4, LOW); + digitalWrite(led5, LOW); +} +//-----------------------------------------------------------------------// +void setup() { + Serial.begin(9600); + pinMode(led1, OUTPUT); + pinMode(led2, OUTPUT); + pinMode(led3, OUTPUT); + pinMode(led4, OUTPUT); + pinMode(led5, OUTPUT); +} + +void loop() { + while (Serial.available()){ + delay(50); + char chunk = Serial.read(); //Data chunk recieved by the HC05 Module + if (chunk == '#') {break;} //Empty Data Chunk + voice += chunk; //Constructing instruction using data chunks + } + if (voice.length() > 0) { + Serial.println(voice); +//-----------------------------------------------------------------------// + //----------Control Multiple Pins/ LEDs----------// + if(voice == "*all on") {allon();} //Turn Off All Pins (Call Function) + else if(voice == "*all off"){alloff();} //Turn On All Pins (Call Function) + + //----------Turn On One-By-One----------// + else if(voice == "*L1 on") {digitalWrite(led1, HIGH);} + else if(voice == "*L2 on") {digitalWrite(led2, HIGH);} + else if(voice == "*L3 on") {digitalWrite(led3, HIGH);} + else if(voice == "*L4 on") {digitalWrite(led4, HIGH);} + else if(voice == "*L5 on") {digitalWrite(led5, HIGH);} + //----------Turn Off One-By-One----------// + else if(voice == "*L1 off") {digitalWrite(led1, LOW);} + else if(voice == "*L2 off") {digitalWrite(led2, LOW);} + else if(voice == "*L3 off") {digitalWrite(led3, LOW);} + else if(voice == "*L4 off") {digitalWrite(led4, LOW);} + else if(voice == "*L5 off") {digitalWrite(led5, LOW);} +//-----------------------------------------------------------------------// +voice="";}} //Reset the variable after initiating diff --git a/Arduino_Code/kittybot.ino b/Arduino_Code/kittybot.ino new file mode 100644 index 000000000..61eab8508 --- /dev/null +++ b/Arduino_Code/kittybot.ino @@ -0,0 +1,62 @@ +/* Sweep + by BARRAGAN + This example code is in the public domain. + + modified 8 Nov 2013 + by Scott Fitzgerald + http://www.arduino.cc/en/Tutorial/Sweep +*/ + +#include + + Servo s1,s2,s3,s4; // created on most boards + + +int pos = 0; // variable to store the servo position +int t=2000; +void setup() { + s1.attach(6);// attaches the servo on pin 9 to the servo object + s1.write(50); + s2.attach(5); + s2.write(90); + s3.attach(9); // attaches the servo on pin 9 to the servo object + s3.write(55); + s4.attach(3); + s4.write(90); +} + +void loop() { + + s1.write(30); + delay(t); + s1.write(40); + delay(t); + s3.write(95); + delay(t); + s1.write(50); + delay(t); + s3.write(75); + delay(t); + s4.write(50); + delay(t); + s3.write(55); + delay(t); + s4.write(70); + delay(t); + s2.write(110); + delay(t); + s4.write(90); + delay(t); + s2.write(90); + +//for (pos = 0; pos <= 180; pos += 90) { // goes from 0 degrees to 180 degrees +// // in steps of 1 degree +// myservo.write(pos); // tell servo to go to position in variable 'pos' +// delay(100); // waits 15ms for the servo to reach the position +// } +// for (pos = 180; pos >= 0; pos -= 90) { // goes from 180 degrees to 0 degrees +// myservo.write(pos); // tell servo to go to position in variable 'pos' +// delay(); // waits 15ms for the servo to reach the position +// } +} + diff --git a/Arduino_Code/setup.ino b/Arduino_Code/setup.ino new file mode 100644 index 000000000..7a4679c0a --- /dev/null +++ b/Arduino_Code/setup.ino @@ -0,0 +1,20 @@ +#include +Servo s1, s2, s3, s4; + +void setup() +{s1.attach(6);// attaches the servo on pin 9 to the servo object + s1.write(90); + s2.attach(5); + s2.write(90); + s3.attach(9); // attaches the servo on pin 9 to the servo object + s3.write(90); + s4.attach(3); + s4.write(90); + +} +void loop() +{ + s1.write(30); + s2.write(40); +} + diff --git a/Backtracking/Knight tour problem/c/knight_tour_problem.c b/Backtracking/Knight tour problem/c/knight_tour_problem.c new file mode 100644 index 000000000..61203154f --- /dev/null +++ b/Backtracking/Knight tour problem/c/knight_tour_problem.c @@ -0,0 +1,104 @@ +/* The knight is placed on the first block of an empty + * board and, moving according to the rules of chess, must + * visit each square exactly once. + */ + + +// C program for Knight Tour problem +#include +#define N 8 + +int solveKTUtil(int x, int y, int movei, int sol[N][N], + int xMove[], int yMove[]); + +/* A utility function to check if i,j are valid indexes + for N*N chessboard */ +bool isSafe(int x, int y, int sol[N][N]) +{ + return ( x >= 0 && x < N && y >= 0 && + y < N && sol[x][y] == -1); +} + +/* A utility function to print solution matrix sol[N][N] */ +void printSolution(int sol[N][N]) +{ + for (int x = 0; x < N; x++) + { + for (int y = 0; y < N; y++) + printf(" %2d ", sol[x][y]); + printf("\n"); + } +} + +/* This function solves the Knight Tour problem using + Backtracking. This function mainly uses solveKTUtil() + to solve the problem. It returns false if no complete + tour is possible, otherwise return true and prints the + tour. + Please note that there may be more than one solutions, + this function prints one of the feasible solutions. */ +bool solveKT() +{ + int sol[N][N]; + + /* Initialization of solution matrix */ + for (int x = 0; x < N; x++) + for (int y = 0; y < N; y++) + sol[x][y] = -1; + + /* xMove[] and yMove[] define next move of Knight. + xMove[] is for next value of x coordinate + yMove[] is for next value of y coordinate */ + int xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 }; + int yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 }; + + // Since the Knight is initially at the first block + sol[0][0] = 0; + + /* Start from 0,0 and explore all tours using + solveKTUtil() */ + if (solveKTUtil(0, 0, 1, sol, xMove, yMove) == false) + { + printf("Solution does not exist"); + return false; + } + else + printSolution(sol); + + return true; +} + +/* A recursive utility function to solve Knight Tour + problem */ +int solveKTUtil(int x, int y, int movei, int sol[N][N], + int xMove[N], int yMove[N]) +{ + int k, next_x, next_y; + if (movei == N*N) + return true; + + /* Try all next moves from the current coordinate x, y */ + for (k = 0; k < 8; k++) + { + next_x = x + xMove[k]; + next_y = y + yMove[k]; + if (isSafe(next_x, next_y, sol)) + { + sol[next_x][next_y] = movei; + if (solveKTUtil(next_x, next_y, movei+1, sol, + xMove, yMove) == true) + return true; + else + sol[next_x][next_y] = -1;// backtracking + } + } + + return false; +} + +/* Driver program to test above functions */ +int main() +{ + solveKT(); + return 0; +} diff --git a/Backtracking/Magic Squares/Python/magic_squares.py b/Backtracking/Magic Squares/Python/magic_squares.py new file mode 100644 index 000000000..bb8056a94 --- /dev/null +++ b/Backtracking/Magic Squares/Python/magic_squares.py @@ -0,0 +1,87 @@ +""" +Magic square is a square filled with numbers starting with one +in a way that the sum of each row, column and diagonal is the same. + +The following algorithm uses a recursive approach, it could +be implemented iteratively but the algorithm would be way longer. + +""" + + +import time + +start = time.time() + + +def expected_row_sum(square_size): + """Calculates the expected row sum based on square size.""" + return int(sum(range(1, square_size ** 2 + 1)) / square_size) + + +def get_column(square_size, square, i): + """Returns an i-th column of a square.""" + expected_modulo = i % square_size + col = [] + for i, item in enumerate(square): + if i % square_size == expected_modulo: + col.append(item) + return col + + +def magic_squares(square_size, square=None, used=None, i=0): + if square is None: + square = [None for _ in range(square_size ** 2)] + if used is None: + used = [False for _ in range(square_size ** 2)] + row_sum = expected_row_sum(square_size) + if i == square_size ** 2: + # left to right diagonal, for size 3, the indexes are 0, 4, 8 (increments by 4 to get the next field so that + # is square_size + 1) + d1_sum = 0 + for j in range(square_size): + d1_sum += square[j * (square_size + 1)] + # right to left diagonal, for size 3, the indexes are 2, 4, 6 (increments by 2 to get the next field so that + # is square_size - 1. Also starts at 2 not 0. + d2_sum = 0 + for j in range(square_size): + d2_sum += square[(j + 1) * (square_size - 1)] + + if d1_sum == row_sum and d2_sum == row_sum: + cp = list(square) + yield [[cp.pop(0) for _ in range(square_size)] for __ in range(square_size)] + else: + # try to insert all possible numbers - backtracking + for n in range(1, square_size ** 2 + 1): + square[i] = n + if not used[n - 1]: + # check row sum after each row + if (i + 1) % square_size == 0: + if sum(square[i - square_size + 1: i + 1]) != row_sum: + continue + # if we are on the last line, check column + if i >= square_size * (square_size - 1): + if sum(get_column(square_size, square, i)) != row_sum: + continue + used[n - 1] = True + + else: + continue + + # yield from gets the result from the lowest recursion level, works only in py 3.3+, slower alternative: + # for s in magic_squares(square_size, square, used, i + 1): + # yield s + yield from magic_squares(square_size, square, used, i + 1) + # reset to the previous state + used[n - 1] = False + + +number_of_solutions = 0 +for sq in magic_squares(3): + number_of_solutions += 1 + for line in sq: + print(' '.join([str(x) for x in line])) + print('\n') + +print(number_of_solutions) + +print('--- %s seconds ---' % (time.time() - start)) diff --git a/Backtracking/Nqueens.java b/Backtracking/Nqueens.java new file mode 100644 index 000000000..a706ea712 --- /dev/null +++ b/Backtracking/Nqueens.java @@ -0,0 +1,63 @@ +import java.io.*; +import java.util.*; + + +public class Nqueens +{ + static HashSet ldia = new HashSet(); + static HashSet rdia = new HashSet(); + public static void find(int count,int ro,HashSet row,HashSet col,int A,ArrayList temp,StringBuilder build,StringBuilder dummy,ArrayList> ans) + { + if(count == A) + { + ans.add(new ArrayList(temp)); + return; + } + for(int i=0;i> solveNQueens(int A) + { + StringBuilder build = new StringBuilder(); + StringBuilder dummy = new StringBuilder(); + ArrayList> ans = new ArrayList<>(); + for(int i=0;i row = new HashSet<>(); + HashSet col = new HashSet<>(); + ArrayList temp = new ArrayList<>(); + find(0,0,row,col,A,temp,build,dummy,ans); + return ans; + } + public static void main(String[] args) + { + Scanner in = new Scanner(System.in); + System.out.print("Enter the size of ChessBoard : "); + int n = in.nextInt(); + ArrayList> ans = solveNQueens(n); + for(int i=0;i temp = ans.get(i); + for(int j=0;j + +void troca(int vetor[], int i, int j) +{ + int aux = vetor[i]; + vetor[i] = vetor[j]; + vetor[j] = aux; +} + +void permuta(int vetor[], int inf, int sup) +{ + if(inf == sup) + { + for(int i = 0; i <= sup; i++) + printf("%d ", vetor[i]); + printf("\n"); + } + else + { + for(int i = inf; i <= sup; i++) + { + troca(vetor, inf, i); + permuta(vetor, inf + 1, sup); + troca(vetor, inf, i); + } + } +} + +int main(int argc, char *argv[]) +{ + int v[] = {1, 2, 3, 4}; + int tam_v = sizeof(v) / sizeof(int); + + permuta(v, 0, tam_v - 1); + + return 0; +} diff --git a/Backtracking/Rat in a Maze/C/rat_in_a_maze.c b/Backtracking/Rat in a Maze/C/rat_in_a_maze.c new file mode 100644 index 000000000..d2c1b407c --- /dev/null +++ b/Backtracking/Rat in a Maze/C/rat_in_a_maze.c @@ -0,0 +1,107 @@ +/* +A Maze is given as N*N binary matrix of blocks where source block is +the upper left most block i.e., maze[0][0] and destination block is lower +rightmost block i.e., maze[N-1][N-1]. A rat starts from source and has to +reach the destination. The rat can move only in two directions: forward and down. +*/ + + +/* C program to solve Rat in a Maze problem using + backtracking */ +#include + +// Maze size +#define N 4 + +bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N]); + +/* A utility function to print solution matrix sol[N][N] */ +void printSolution(int sol[N][N]) +{ + for (int i = 0; i < N; i++) + { + for (int j = 0; j < N; j++) + printf(" %d ", sol[i][j]); + printf("\n"); + } +} + +/* A utility function to check if x,y is valid index for N*N maze */ +bool isSafe(int maze[N][N], int x, int y) +{ + // if (x,y outside maze) return false + if(x >= 0 && x < N && y >= 0 && y < N && maze[x][y] == 1) + return true; + + return false; +} + +/* This function solves the Maze problem using Backtracking. It mainly + uses solveMazeUtil() to solve the problem. It returns false if no + path is possible, otherwise return true and prints the path in the + form of 1s. Please note that there may be more than one solutions, + this function prints one of the feasible solutions.*/ +bool solveMaze(int maze[N][N]) +{ + int sol[N][N] = { {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }; + + if(solveMazeUtil(maze, 0, 0, sol) == false) + { + printf("Solution doesn't exist"); + return false; + } + + printSolution(sol); + return true; +} + +/* A recursive utility function to solve Maze problem */ +bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N]) +{ + // if (x,y is goal) return true + if(x == N-1 && y == N-1) + { + sol[x][y] = 1; + return true; + } + + // Check if maze[x][y] is valid + if(isSafe(maze, x, y) == true) + { + // mark x,y as part of solution path + sol[x][y] = 1; + + /* Move forward in x direction */ + if (solveMazeUtil(maze, x+1, y, sol) == true) + return true; + + /* If moving in x direction doesn't give solution then + Move down in y direction */ + if (solveMazeUtil(maze, x, y+1, sol) == true) + return true; + + /* If none of the above movements work then BACKTRACK: + unmark x,y as part of solution path */ + sol[x][y] = 0; + return false; + } + + return false; +} + +// driver program to test above function +int main() +{ + int maze[N][N] = { {1, 0, 0, 0}, + {1, 1, 0, 1}, + {0, 1, 0, 0}, + {1, 1, 1, 1} + }; + + solveMaze(maze); + return 0; +} diff --git a/Backtracking/Sudoku solution/C/sudoku.c b/Backtracking/Sudoku solution/C/sudoku.c new file mode 100644 index 000000000..cd99286ef --- /dev/null +++ b/Backtracking/Sudoku solution/C/sudoku.c @@ -0,0 +1,133 @@ + +// A Backtracking program in C to solve Sudoku problem +#include + +// UNASSIGNED is used for empty cells in sudoku grid +#define UNASSIGNED 0 + +// N is used for the size of Sudoku grid. Size will be NxN +#define N 9 + +// This function finds an entry in grid that is still unassigned +bool FindUnassignedLocation(int grid[N][N], int &row, int &col); + +// Checks whether it will be legal to assign num to the given row, col +bool isSafe(int grid[N][N], int row, int col, int num); + +/* Takes a partially filled-in grid and attempts to assign values to + all unassigned locations in such a way to meet the requirements + for Sudoku solution (non-duplication across rows, columns, and boxes) */ +bool SolveSudoku(int grid[N][N]) +{ + int row, col; + + // If there is no unassigned location, we are done + if (!FindUnassignedLocation(grid, row, col)) + return true; // success! + + // consider digits 1 to 9 + for (int num = 1; num <= 9; num++) + { + // if looks promising + if (isSafe(grid, row, col, num)) + { + // make tentative assignment + grid[row][col] = num; + + // return, if success, yay! + if (SolveSudoku(grid)) + return true; + + // failure, unmake & try again + grid[row][col] = UNASSIGNED; + } + } + return false; // this triggers backtracking +} + +/* Searches the grid to find an entry that is still unassigned. If + found, the reference parameters row, col will be set the location + that is unassigned, and true is returned. If no unassigned entries + remain, false is returned. */ +bool FindUnassignedLocation(int grid[N][N], int &row, int &col) +{ + for (row = 0; row < N; row++) + for (col = 0; col < N; col++) + if (grid[row][col] == UNASSIGNED) + return true; + return false; +} + +/* Returns a boolean which indicates whether an assigned entry + in the specified row matches the given number. */ +bool UsedInRow(int grid[N][N], int row, int num) +{ + for (int col = 0; col < N; col++) + if (grid[row][col] == num) + return true; + return false; +} + +/* Returns a boolean which indicates whether an assigned entry + in the specified column matches the given number. */ +bool UsedInCol(int grid[N][N], int col, int num) +{ + for (int row = 0; row < N; row++) + if (grid[row][col] == num) + return true; + return false; +} + +/* Returns a boolean which indicates whether an assigned entry + within the specified 3x3 box matches the given number. */ +bool UsedInBox(int grid[N][N], int boxStartRow, int boxStartCol, int num) +{ + for (int row = 0; row < 3; row++) + for (int col = 0; col < 3; col++) + if (grid[row+boxStartRow][col+boxStartCol] == num) + return true; + return false; +} + +/* Returns a boolean which indicates whether it will be legal to assign + num to the given row,col location. */ +bool isSafe(int grid[N][N], int row, int col, int num) +{ + /* Check if 'num' is not already placed in current row, + current column and current 3x3 box */ + return !UsedInRow(grid, row, num) && + !UsedInCol(grid, col, num) && + !UsedInBox(grid, row - row%3 , col - col%3, num); +} + +/* A utility function to print grid */ +void printGrid(int grid[N][N]) +{ + for (int row = 0; row < N; row++) + { + for (int col = 0; col < N; col++) + printf("%2d", grid[row][col]); + printf("\n"); + } +} + +/* Driver Program to test above functions */ +int main() +{ + // 0 means unassigned cells + int grid[N][N] = {{3, 0, 6, 5, 0, 8, 4, 0, 0}, + {5, 2, 0, 0, 0, 0, 0, 0, 0}, + {0, 8, 7, 0, 0, 0, 0, 3, 1}, + {0, 0, 3, 0, 1, 0, 0, 8, 0}, + {9, 0, 0, 8, 6, 3, 0, 0, 5}, + {0, 5, 0, 0, 9, 0, 6, 0, 0}, + {1, 3, 0, 0, 0, 0, 2, 5, 0}, + {0, 0, 0, 0, 0, 0, 0, 7, 4}, + {0, 0, 5, 2, 0, 6, 3, 0, 0}}; + if (SolveSudoku(grid) == true) + printGrid(grid); + else + printf("No solution exists"); + + return 0; +} diff --git a/Backtracking/Tower of Hanoi/tower_of_hanoi.cpp b/Backtracking/Tower of Hanoi/tower_of_hanoi.cpp new file mode 100644 index 000000000..3bb602329 --- /dev/null +++ b/Backtracking/Tower of Hanoi/tower_of_hanoi.cpp @@ -0,0 +1,22 @@ +#include +using namespace std; +void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod) +{ + if (n == 1) + { + printf("\n Move disk 1 from rod %c to rod %c", from_rod, to_rod); + return; + } + towerOfHanoi(n-1, from_rod, aux_rod, to_rod); + printf("\n Move disk %d from rod %c to rod %c", n, from_rod, to_rod); + towerOfHanoi(n-1, aux_rod, to_rod, from_rod); +} + +int main() +{ + int n; + cout<<"\n Enter Number of Disks "; + cin>>n; + towerOfHanoi(n, 'A', 'C', 'B'); + return 0; +} diff --git a/Backtracking/mcoloring/mcoloring.py b/Backtracking/mcoloring/mcoloring.py new file mode 100644 index 000000000..6d58f929a --- /dev/null +++ b/Backtracking/mcoloring/mcoloring.py @@ -0,0 +1,46 @@ + +class Graph(): + + def __init__(self, vertices): + self.V = vertices + self.graph = [[0 for column in range(vertices)]\ + for row in range(vertices)] + + # A utility function to check if the current color assignment + # is safe for vertex v + def isSafe(self, v, colour, c): + for i in range(self.V): + if self.graph[v][i] == 1 and colour[i] == c: + return False + return True + + # A recursive utility function to solve m + # coloring problem + def graphColourUtil(self, m, colour, v): + if v == self.V: + return True + + for c in range(1, m+1): + if self.isSafe(v, colour, c) == True: + colour[v] = c + if self.graphColourUtil(m, colour, v+1) == True: + return True + colour[v] = 0 + + def graphColouring(self, m): + colour = [0] * self.V + if self.graphColourUtil(m, colour, 0) == False: + return False + + # Print the solution + print "Solution exist and Following are the assigned colours:" + for c in colour: + print c, + return True + +# Driver Code +g = Graph(4) +g.graph = [[0,1,1,1], [1,0,1,0], [1,1,0,1], [1,0,1,0]] +m=3 +g.graphColouring(m) + diff --git a/Backtracking/mcoloring/mcoloring.py.txt b/Backtracking/mcoloring/mcoloring.py.txt new file mode 100644 index 000000000..6d58f929a --- /dev/null +++ b/Backtracking/mcoloring/mcoloring.py.txt @@ -0,0 +1,46 @@ + +class Graph(): + + def __init__(self, vertices): + self.V = vertices + self.graph = [[0 for column in range(vertices)]\ + for row in range(vertices)] + + # A utility function to check if the current color assignment + # is safe for vertex v + def isSafe(self, v, colour, c): + for i in range(self.V): + if self.graph[v][i] == 1 and colour[i] == c: + return False + return True + + # A recursive utility function to solve m + # coloring problem + def graphColourUtil(self, m, colour, v): + if v == self.V: + return True + + for c in range(1, m+1): + if self.isSafe(v, colour, c) == True: + colour[v] = c + if self.graphColourUtil(m, colour, v+1) == True: + return True + colour[v] = 0 + + def graphColouring(self, m): + colour = [0] * self.V + if self.graphColourUtil(m, colour, 0) == False: + return False + + # Print the solution + print "Solution exist and Following are the assigned colours:" + for c in colour: + print c, + return True + +# Driver Code +g = Graph(4) +g.graph = [[0,1,1,1], [1,0,1,0], [1,1,0,1], [1,0,1,0]] +m=3 +g.graphColouring(m) + diff --git a/Bit Manipulation/Brian_Kernighan_Algorithm.c b/Bit Manipulation/Brian_Kernighan_Algorithm.c new file mode 100644 index 000000000..c7840aae5 --- /dev/null +++ b/Bit Manipulation/Brian_Kernighan_Algorithm.c @@ -0,0 +1,24 @@ + +#include + +/* Count set bits */ +unsigned int countSetBits(int num) +{ + unsigned int count = 0; + while (num) + { + num &= (num-1) ; + count++; + } + return count; +} + +/* Program to test function countSetBits */ +int main() +{ + /* count set bits in 9 */ + int numnum = 9; + printf("%d", countSetBits(numnum)); + getchar(); + return 0; +} diff --git a/Bit Manipulation/EvenOrOdd/even_or_odd.c b/Bit Manipulation/EvenOrOdd/even_or_odd.c new file mode 100644 index 000000000..c6fc710e6 --- /dev/null +++ b/Bit Manipulation/EvenOrOdd/even_or_odd.c @@ -0,0 +1,23 @@ +#include + +void main(void){ + + //quick test to see if number is even or odd + //lsb toggles every time you increment a number + //0 - 0000 - even + //1 - 0001 - odd + //2 - 0010 - even + //3 - 0011 - odd + //4 - 0100 - even + //5 - 0101 - odd + //etc + //pretty dope + for(int evenodd = 0; evenodd <= 10; evenodd++){ + if(evenodd & 0x1){ + printf("%i is odd\n", evenodd); + }else{ + printf("%i is even\n", evenodd); + } + } + +} diff --git a/Bit Manipulation/EvenOrOdd/evenodd.py b/Bit Manipulation/EvenOrOdd/evenodd.py new file mode 100644 index 000000000..d1436b194 --- /dev/null +++ b/Bit Manipulation/EvenOrOdd/evenodd.py @@ -0,0 +1,9 @@ +def isEven(n) : + return (n & 1); + +n = 101; +if(isEven(n) == 0) : + print ("Even"); +else : + print ("Odd"); + diff --git a/Bit Manipulation/EvenOrOdd/evenorodd.cs b/Bit Manipulation/EvenOrOdd/evenorodd.cs new file mode 100644 index 000000000..0e390045c --- /dev/null +++ b/Bit Manipulation/EvenOrOdd/evenorodd.cs @@ -0,0 +1,15 @@ +using System; + +public class Program +{ + public static void Main() + { + for (int i = 0; i < 10; i++) { + if ((i&1) == 1) { + Console.WriteLine(i + " odd"); + } else { + Console.WriteLine(i + " even"); + } + } + } +} diff --git a/Bit Manipulation/EvenOrOdd/evenorodd.go b/Bit Manipulation/EvenOrOdd/evenorodd.go new file mode 100644 index 000000000..cb4182c8b --- /dev/null +++ b/Bit Manipulation/EvenOrOdd/evenorodd.go @@ -0,0 +1,15 @@ +package main + +import ( + "fmt" +) + +func main() { + for i := 0; i < 10; i++ { + if i&1 == 1 { + fmt.Println(i, "is odd") + } else { + fmt.Println(i, "is even") + } + } +} diff --git a/Bit Manipulation/FlipBits/FlipBits.java b/Bit Manipulation/FlipBits/FlipBits.java new file mode 100644 index 000000000..a956aac84 --- /dev/null +++ b/Bit Manipulation/FlipBits/FlipBits.java @@ -0,0 +1,27 @@ +//Counting the number of flipped bits to be flipped to covert A into B +import java.util.*; +import java.lang.*; +import java.io.*; + +/* Name of the class has to be "Main" only if the class is public. */ +public class FlipBits +{ + public static long countFlippedBits(long A,long B){ + long ans=A^B; + long count=0; + while(ans>0){ + count+=ans&1; + ans>>=1; + } + return count; + } + public static void main (String[] args) throws java.lang.Exception + { + // your code goes here + Scanner scan=new Scanner(System.in); + long A=scan.nextLong(); + long B=scan.nextLong(); + long ans=countFlippedBits(A,B); + System.out.println(ans); + } +} diff --git a/Bit Manipulation/GeneratingEverySubsetWithBitmask/EverySubset.cpp b/Bit Manipulation/GeneratingEverySubsetWithBitmask/EverySubset.cpp new file mode 100644 index 000000000..74ec8253d --- /dev/null +++ b/Bit Manipulation/GeneratingEverySubsetWithBitmask/EverySubset.cpp @@ -0,0 +1,28 @@ +#include +using namespace std; +vectorVector; int Size; +void Solve(){ + cout << "All possible subsets are:\n"; + int Index = 1; + for (int i = 0; i < (1 << Size); i++){ + cout << Index << ") "; + for (int j = 0; j < Size; j++){ + if (i & (1 << j)){ + cout << Vector[j] << ' '; + } + } + Index++; + cout << '\n'; + } +} +int main(){ + cout << "Enter size of vector:\n"; + cin >> Size; + cout << "Enter your vector elements:\n"; + for (int i = 0; i < Size; i++){ + int Element; cin >> Element; + Vector.push_back(Element); + } + Solve(); + return 0; +} diff --git a/Bit Manipulation/countSet/c/count-set-bits.c b/Bit Manipulation/countSet/c/count-set-bits.c index e76b22c8f..b3ca9a051 100644 --- a/Bit Manipulation/countSet/c/count-set-bits.c +++ b/Bit Manipulation/countSet/c/count-set-bits.c @@ -9,7 +9,8 @@ int countSimple(int n) { // If the last bit is set, add one to the counter count += n & 0x1; // Shift one place to the right - n >>= 1; + //avoid issues from signed extension if int is negative + n = (n >> 1) & 0x7fffffff; iterations++; } diff --git a/Bit Manipulation/countSet/cpp/Count-set-bits.cpp b/Bit Manipulation/countSet/cpp/Count-set-bits.cpp index 6ee073c94..1d15d7015 100644 --- a/Bit Manipulation/countSet/cpp/Count-set-bits.cpp +++ b/Bit Manipulation/countSet/cpp/Count-set-bits.cpp @@ -1,7 +1,15 @@ #include using namespace std; -int main() { - cout << __builtin_popcount (4) << "\n"; +int main() { + cout << "Enter an integer: "; + cin >> input; + while(cin.fail()) { + cout << "Invalid input. Please re-enter: " << endl; + cin.clear(); + cin.ignore(256,'\n'); + cin >> input; + } + cout << __builtin_popcount (input) << "\n"; return 0; } diff --git a/Bit Manipulation/countSet/go/countSetBits.go b/Bit Manipulation/countSet/go/countSetBits.go new file mode 100644 index 000000000..91f57f784 --- /dev/null +++ b/Bit Manipulation/countSet/go/countSetBits.go @@ -0,0 +1,34 @@ +package main + +import( + "fmt" +) + +func countSetBits(n int) int { + var p int = 0 + + for (n > 0) { + + if (n % 2 == 1){ + p++ + } + + n >>= 1 + + } + + return p +} + +func main(){ + var input int + + fmt.Println("The Point of this program is to compute\nNumber of set", + "bits in the number entered.\nPlease enter a number") + + _,err := fmt.Scanf("%d",&input) + if err != nil { + fmt.Println("Invalid input") + } + fmt.Printf("Number of Set bits in %d is %d\n",input,countSetBits(input)) +} diff --git a/Bit Manipulation/countSet/java/count-set-bits.java b/Bit Manipulation/countSet/java/count-set-bits.java new file mode 100644 index 000000000..e2a65fcd2 --- /dev/null +++ b/Bit Manipulation/countSet/java/count-set-bits.java @@ -0,0 +1,13 @@ +public class countSet { + public static void main(String[] args) { + int n; + try{ + n = Integer.parseInt(args[0]); + System.out.println("Number is : " + n); + System.out.println("Number of bits = " + Integer.bitCount(n)); + } catch (NumberFormatException e) { + System.out.println("Given input is not a valid integer."); + System.exit(1); + } + } +} \ No newline at end of file diff --git a/Bit Manipulation/next power of 2/go/nextPowerOf2.go b/Bit Manipulation/next power of 2/go/nextPowerOf2.go new file mode 100644 index 000000000..5b21706e1 --- /dev/null +++ b/Bit Manipulation/next power of 2/go/nextPowerOf2.go @@ -0,0 +1,32 @@ +package main + +import( + "fmt" +) + +func next2pow(n int) int { + var p int = 1 + + if( n > 0 && (n & (n-1)) == 0){ + return n + } + + for (p < n) { + p <<= 1 + } + + return p +} + +func main(){ + var input int + + fmt.Println("The Point of this program is to compute\nSmallest power of two ", + "greater than or eqaul to the number entered.\nPlease enter a number") + + _,err := fmt.Scanf("%d",&input) + if err != nil { + fmt.Println("Invalid input") + } + fmt.Printf("Smallest Power of 2 greater than or equal to %d is %d\n",input,next2pow(input)) +} diff --git a/Bit Manipulation/power of 2/cpp/power_of_2.cpp b/Bit Manipulation/power of 2/cpp/power_of_2.cpp new file mode 100644 index 000000000..17ff82c09 --- /dev/null +++ b/Bit Manipulation/power of 2/cpp/power_of_2.cpp @@ -0,0 +1,16 @@ +#include + +using namespace std; + +bool is_power_of_2(int x) { + return (x & (x - 1)) == 0; +} + +int main() { + int x; + + cin >> x; + cout << is_power_of_2(x); + + return 0; +} \ No newline at end of file diff --git a/Bit Manipulation/power of 4/cpp/power_of_4.cpp b/Bit Manipulation/power of 4/cpp/power_of_4.cpp new file mode 100644 index 000000000..2685685b1 --- /dev/null +++ b/Bit Manipulation/power of 4/cpp/power_of_4.cpp @@ -0,0 +1,34 @@ +/* Power of 2 can be found by (n&(n-1) == 0 + * Because it will have only one set bit + * For power of 4 we have to check the even + * positions for the set bit + * So we & it with 10101010101010101010101010101010 + * It can also be written as 0xAAAAAAAA + * If (n & 0xAAAAAAAA) == 0 then n is power of 4 +*/ + +#include +using namespace std; +typedef long long ll; +typedef double dl; +#define mem(x,val) memset((x),(val),sizeof(x)) +#define pb push_back +#define mod 1000000007 + +bool poweroffour(int n) +{ + return (n && !(n&(n-1)) && !(n & 0xAAAAAAAA)); +} +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + + int n; + cin>>n; + if(poweroffour(n)) + cout< +using namespace std; +typedef long long ll; +typedef double dl; +#define mem(x,val) memset((x),(val),sizeof(x)) +#define pb push_back +#define mod 1000000007 +int subsetXOR(int arr[],int n,int k) +{ + int max_ele=*max_element(arr,arr+n); + int m=(1<<(int)log2(max_ele)+1)-1; + + int dp[n+1][m+1]; + + for(int i=0;i<=n;i++) + { + for(int j=0;j<=m;j++) + dp[i][j]=0; + } + + dp[0][0]=1; + for(int i=1;i<=n;i++) + { + for(int j=0;j<=m;j++) + dp[i][j]=dp[i-1][j]+dp[i][j^arr[i-1]]; + } + return dp[n][k]; +} +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + + int n; + cin>>n; + int arr[n]; + for(int i=0;i>arr[i]; + int k; + cin>>k; + cout< Mining New Block -->") +CEVcoin.mineBlock(data) + +print("\n\n ----> New Block mined successfully --> ") + +CEVcoin.printBlockchain() diff --git a/Branch And Bound/0_1 Knapsack/CPP/0_1Knapsack.cpp b/Branch And Bound/0_1 Knapsack/CPP/0_1Knapsack.cpp new file mode 100644 index 000000000..23ff6adea --- /dev/null +++ b/Branch And Bound/0_1 Knapsack/CPP/0_1Knapsack.cpp @@ -0,0 +1,100 @@ +#include +using namespace std; + +struct Item +{ + float weight; + int value; +}; + +struct Node +{ + int level, profit, bound; + float weight; +}; + +bool cmp(Item a, Item b) +{ + double r1 = (double)a.value / a.weight; + double r2 = (double)b.value / b.weight; + return r1 > r2; +} + +int bound(Node u, int n, int W, Item arr[]) +{ + if (u.weight >= W) + return 0; + + int profit_bound = u.profit; + + int j = u.level + 1; + int totweight = u.weight; + + while ((j < n) && (totweight + arr[j].weight <= W)) + { + totweight += arr[j].weight; + profit_bound += arr[j].value; + j++; + } + if (j < n) + profit_bound += (W - totweight) * arr[j].value / + arr[j].weight; + + return profit_bound; +} + +int knapsack(int W, Item arr[], int n) +{ + sort(arr, arr + n, cmp); + + queue Q; + Node u, v; + + u.level = -1; + u.profit = u.weight = 0; + Q.push(u); + + int maxProfit = 0; + while (!Q.empty()) + { + u = Q.front(); + Q.pop(); + if (u.level == -1) + v.level = 0; + if (u.level == n-1) + continue; + v.level = u.level + 1; + + v.weight = u.weight + arr[v.level].weight; + v.profit = u.profit + arr[v.level].value; + + if (v.weight <= W && v.profit > maxProfit) + maxProfit = v.profit; + + v.bound = bound(v, n, W, arr); + + if (v.bound > maxProfit) + Q.push(v); + + v.weight = u.weight; + v.profit = u.profit; + v.bound = bound(v, n, W, arr); + if (v.bound > maxProfit) + Q.push(v); + } + + return maxProfit; +} + +int main() +{ + int W = 10; + Item arr[] = {{2, 40}, {3.14, 50}, {1.98, 100}, + {5, 95}, {3, 30}}; + int n = sizeof(arr) / sizeof(arr[0]); + + cout << "Maximum possible profit = " + << knapsack(W, arr, n); + + return 0; +} diff --git a/Branch And Bound/0_1 Knapsack/README.md b/Branch And Bound/0_1 Knapsack/README.md new file mode 100644 index 000000000..99ccb10ce --- /dev/null +++ b/Branch And Bound/0_1 Knapsack/README.md @@ -0,0 +1,26 @@ +# 0/1 Knapsack Problem (using BRANCH & BOUND) + +## Problem: + +1. Given two integer arrays val[0..n-1] and wt[0..n-1] that represent values and weights associated with n items respectively. +2. Find out the maximum value subset of val[] such that sum of the weights of this subset is smaller than or equal to Knapsack capacity W. +3. We have ‘n’ items with value v1 , v2 . . . vn and weight of the corresponding items is w1 , w2 . . . Wn . Max capacity is W . +4. We can either choose or not choose an item. We have x1 , x2 . . . xn. Here xi = { 1 , 0 }. xi = 1 , item chosen xi = 0 , item not chosen. + +## Why Branch And Bound? +- Greedy approach works only for fractional knapsack problem. +- If weights are not integers , dynamic programming will not work. +- There are 2n possible combinations of item , complexity for brute force goes exponentially. + +## Algorithm: +1. Sort all items in decreasing order of ratio of value per unit weight so that an upper bound can be computed using Greedy Approach. +2. Initialize maximum profit, maxProfit = 0 +3. Create an empty queue, Q. +4. Create a dummy node of decision tree and enqueue it to Q. + Profit and weight of dummy node are 0. +5. Do following while Q is not empty. + - Extract an item from Q. Let the extracted item be u. + - Compute profit of next level node. If the profit is more than maxProfit, then update maxProfit. + - Compute bound of next level node. If bound is more than maxProfit, then add next level node to Q. + - Consider the case when next level node is not considered as part of solution and add a node to queue with level as next, + but weight and profit without considering next level nodes. diff --git a/Branch And Bound/README.md b/Branch And Bound/README.md new file mode 100644 index 000000000..51cf0a2b2 --- /dev/null +++ b/Branch And Bound/README.md @@ -0,0 +1,20 @@ +# BRANCH AND BOUND + + +- **Branch and bound (BB, B&B, or BnB)** is an algorithm design paradigm for discrete and combinatorial optimization problems, as well as mathematical optimization. +A branch-and-bound algorithm consists of a systematic enumeration of candidate solutions by means of **state space search:** the set of candidate solutions is +thought of as forming a rooted tree with the full set at the root. + +- The algorithm explores branches of this tree, which represent subsets of the solution set. Before enumerating the candidate solutions of a branch, +the branch is checked against upper and lower estimated bounds on the optimal solution, and is discarded if it cannot produce a better solution than the best one found so far by the algorithm. + +- The term branch-and-bound refers to all state space search methods in which all children of the £-node are generated before any other live node can + become the £-node. +- We have already seen two graph search strategies, BFS and D-search, in which the exploration of a new node cannot begin until the node currently + being explored is fully explored. +- Both of these generalize to branch-and-bound strategies. + - In branch-and-bound terminology, a BFS-like state space search will be called FIFO (First In First Out) + search as the list of live nodes is a first-in-first-out list (or queue). + + - A D-search-like state space search will be called LIFO (Last In First Out) + search as the list of live nodes is a last-in-first-out list (or stack diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 43fd67246..028a045cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,13 +2,16 @@ * Contributions are always welcome. Language doesn't matter. Just make sure you're implementing an algorithm. * PRs are welcome. To begin developing, follow the structure: - > Algorithm-Type/algorithm_name/language-name/file_name.extension + > Algorithm-Type/algorithm-name/language-name/file-name.extension + e.g - > Sorting/bubble_sort/python/bubble_sort.py - * Beautify and cleanup your code for easier reading + > Sorting/bubble-sort/python/bubble-sort.py + * If there is an implementation of the same algorithm in your language, do not give a PR for that. * Please include a description for the algorithm that you are implementing. It doesn't matter if it's copied from somewhere as long as it helps people that are learning new algorithm. * Graphical examples would be very helpful too. - * Don't forget to include tests. + * You can include tests as well. * Don't remove previous implementations of algorithms. Just add a new file with your own implementation. - * Beautify and cleanup your code for easier reading + * Beautify and clean up your code for easier reading + ### Note: + * If your PR is closed without any comment, it means that your PR does not meet the above criteria. Make sure your PR is **not Duplicate** and it should be **well-documented**. diff --git a/Combinatorial Game Theory/Alpha-Beta Pruning/AlphaBetaPruning.java b/Combinatorial Game Theory/Alpha-Beta Pruning/AlphaBetaPruning.java new file mode 100644 index 000000000..acc8ed29e --- /dev/null +++ b/Combinatorial Game Theory/Alpha-Beta Pruning/AlphaBetaPruning.java @@ -0,0 +1,44 @@ +// Java program to demonstrate +// working of Alpha-Beta Pruning +import java.io.*; + +class AlphaBetaPruning { + + static int MAX = 1000; + static int MIN = -1000; + static int minimax(int depth, int nodeIndex, Boolean maximizingPlayer, int values[], int alpha, int beta) { + if (depth == 3) + return values[nodeIndex]; + + if (maximizingPlayer) { + int best = MIN; + for (int i = 0; i < 2; i++) { + int val = minimax(depth + 1, nodeIndex * 2 + i, false, values, alpha, beta); + best = Math.max(best, val); + alpha = Math.max(alpha, best); + + if (beta <= alpha) + break; + } + return best; + } else { + int best = MAX; + for (int i = 0; i < 2; i++) { + + int val = minimax(depth + 1, nodeIndex * 2 + i, true, values, alpha, beta); + best = Math.min(best, val); + beta = Math.min(beta, best); + if (beta <= alpha) + break; + } + return best; + } + } + + public static void main(String[] args) { + + int values[] = { 3, 5, 6, 9, 1, 2, 0, -1 }; + System.out.println("The optimal value is : " + minimax(0, 0, true, values, MIN, MAX)); + + } +} diff --git a/Combinatorial Game Theory/Alpha-Beta Pruning/alphabeta.cpp b/Combinatorial Game Theory/Alpha-Beta Pruning/alphabeta.cpp new file mode 100644 index 000000000..54c9e4f74 --- /dev/null +++ b/Combinatorial Game Theory/Alpha-Beta Pruning/alphabeta.cpp @@ -0,0 +1,50 @@ +// C++ program to demonstrate working of Alpha-Beta Pruning +#include + +using namespace std; + +const int MAX = 1000; +const int MIN = -1000; + +int minimax(int depth, int nodeIndex, bool maximizingPlayer, int values[], int alpha, int beta) +{ + + if (depth == 3) + return values[nodeIndex]; + + if (maximizingPlayer) + { + int best = MIN; + + for (int i = 0; i < 2; i++) + { + int val = minimax(depth + 1, nodeIndex * 2 + i, false, values, alpha, beta); + best = max(best, val); + alpha = max(alpha, best); + + if (beta <= alpha) + break; + } + return best; + } + else + { + int best = MAX; + for (int i = 0; i < 2; i++) + { + int val = minimax(depth + 1, nodeIndex * 2 + i, true, values, alpha, beta); + best = min(best, val); + beta = min(beta, best); + if (beta <= alpha) + break; + } + return best; + } +} + +int main() +{ + int values[8] = {3, 5, 6, 9, 1, 2, 0, -1}; + cout << "The optimal value is : " << minimax(0, 0, true, values, MIN, MAX); + return 0; +} diff --git a/Combinatorial Game Theory/Game of NIM/gameNIM.c b/Combinatorial Game Theory/Game of NIM/gameNIM.c new file mode 100644 index 000000000..a253f70b8 --- /dev/null +++ b/Combinatorial Game Theory/Game of NIM/gameNIM.c @@ -0,0 +1,217 @@ +/* A C program to implement Game of Nim. The program + assumes that both players are playing optimally */ +#include +#include +#include + +#define COMPUTER 1 +#define HUMAN 2 + +/* A Structure to hold the two parameters of a move + + A move has two parameters- + 1) pile_index = The index of pile from which stone is + going to be removed + 2) stones_removed = Number of stones removed from the + pile indexed = pile_index */ +struct move +{ + int pile_index; + int stones_removed; +}; + +/* + piles[] -> Array having the initial count of stones/coins + in each piles before the game has started. + n -> Number of piles + + The piles[] are having 0-based indexing*/ + +// A C function to output the current game state. +void showPiles (int piles[], int n) +{ + int i; + printf ("Current Game Status -> "); + for (i=0; i 0) + non_zero_indices [count++] = i; + + (*moves).pile_index = (rand() % (count)); + (*moves).stones_removed = + 1 + (rand() % (piles[(*moves).pile_index])); + piles[(*moves).pile_index] = + piles[(*moves).pile_index] - (*moves).stones_removed; + + if (piles[(*moves).pile_index] < 0) + piles[(*moves).pile_index]=0; + } + return; +} + +// A C function to play the Game of Nim +void playGame(int piles[], int n, int whoseTurn) +{ + printf("\nGAME STARTS\n\n"); + struct move moves; + + while (gameOver (piles, n) == false) + { + showPiles(piles, n); + + makeMove(piles, n, &moves); + + if (whoseTurn == COMPUTER) + { + printf("COMPUTER removes %d stones from pile " + "at index %d\n", moves.stones_removed, + moves.pile_index); + whoseTurn = HUMAN; + } + else + { + printf("HUMAN removes %d stones from pile at " + "index %d\n", moves.stones_removed, + moves.pile_index); + whoseTurn = COMPUTER; + } + } + + showPiles(piles, n); + declareWinner(whoseTurn); + return; +} + +void knowWinnerBeforePlaying(int piles[], int n, + int whoseTurn) +{ + printf("Prediction before playing the game -> "); + + if (calculateNimSum(piles, n) !=0) + { + if (whoseTurn == COMPUTER) + printf("COMPUTER will win\n"); + else + printf("HUMAN will win\n"); + } + else + { + if (whoseTurn == COMPUTER) + printf("HUMAN will win\n"); + else + printf("COMPUTER will win\n"); + } + + return; +} + +// Driver program to test above functions +int main() +{ + // Test Case 1 + int piles[] = {3, 4, 5}; + int n = sizeof(piles)/sizeof(piles[0]); + + // We will predict the results before playing + // The COMPUTER starts first + knowWinnerBeforePlaying(piles, n, COMPUTER); + + // Let us play the game with COMPUTER starting first + // and check whether our prediction was right or not + playGame(piles, n, COMPUTER); + + /* + Test Case 2 + int piles[] = {3, 4, 7}; + int n = sizeof(piles)/sizeof(piles[0]); + + // We will predict the results before playing + // The HUMAN(You) starts first + knowWinnerBeforePlaying (piles, n, COMPUTER); + + // Let us play the game with COMPUTER starting first + // and check whether our prediction was right or not + playGame (piles, n, HUMAN); */ + + return(0); +} diff --git a/Combinatorial Game Theory/Grundy Numbers/grundyNum.cpp b/Combinatorial Game Theory/Grundy Numbers/grundyNum.cpp new file mode 100644 index 000000000..fca8d8c18 --- /dev/null +++ b/Combinatorial Game Theory/Grundy Numbers/grundyNum.cpp @@ -0,0 +1,49 @@ +/* A recursive C++ program to find Grundy Number for + a game which is one-pile version of Nim. + Game Description : The game starts with a pile of + n stones, and the player to move may take any + positive number of stones upto 3 only. + The last player to move wins. */ +#include +using namespace std; + +// A Function to calculate Mex of all the values in +// that set. +int calculateMex(unordered_set Set) +{ + int Mex = 0; + + while (Set.find(Mex) != Set.end()) + Mex++; + + return (Mex); +} + +// A function to Compute Grundy Number of 'n' +// Only this function varies according to the game +int calculateGrundy(int n) +{ + if (n == 0) + return (0); + if (n == 1) + return (1); + if (n == 2) + return (2); + if (n == 3) + return (3); + + unordered_set Set; // A Hash Table + + for (int i=1; i<=3; i++) + Set.insert(calculateGrundy(n - i)); + + return (calculateMex(Set)); +} + +// Driver program to test above functions +int main() +{ + int n = 10; + printf("%d", calculateGrundy(n)); + return (0); +} diff --git a/Combinatorial Game Theory/Minimax Algorithm/minimax.cpp b/Combinatorial Game Theory/Minimax Algorithm/minimax.cpp new file mode 100644 index 000000000..d2c2c4826 --- /dev/null +++ b/Combinatorial Game Theory/Minimax Algorithm/minimax.cpp @@ -0,0 +1,53 @@ +// A simple C++ program to find +// maximum score that +// maximizing player can get. +#include +using namespace std; + +// Returns the optimal value a maximizer can obtain. +// depth is current depth in game tree. +// nodeIndex is index of current node in scores[]. +// isMax is true if current move is +// of maximizer, else false +// scores[] stores leaves of Game tree. +// h is maximum height of Game tree +int minimax(int depth, int nodeIndex, bool isMax, + int scores[], int h) +{ + // Terminating condition. i.e + // leaf node is reached + if (depth == h) + return scores[nodeIndex]; + + // If current move is maximizer, + // find the maximum attainable + // value + if (isMax) + return max(minimax(depth+1, nodeIndex*2, false, scores, h), + minimax(depth+1, nodeIndex*2 + 1, false, scores, h)); + + // Else (If current move is Minimizer), find the minimum + // attainable value + else + return min(minimax(depth+1, nodeIndex*2, true, scores, h), + minimax(depth+1, nodeIndex*2 + 1, true, scores, h)); +} + +// A utility function to find Log n in base 2 +int log2(int n) +{ + return (n==1)? 0 : 1 + log2(n/2); +} + +// Driver code +int main() +{ + // The number of elements in scores must be + // a power of 2. + int scores[] = {3, 5, 2, 9, 12, 5, 23, 23}; + int n = sizeof(scores)/sizeof(scores[0]); + int h = log2(n); + int res = minimax(0, 0, true, scores, h); + cout << "The optimal value is : " << res << endl; + return 0; +} diff --git a/Combinatorial Game Theory/Sprague-Grundy Theorem/sprague.cpp b/Combinatorial Game Theory/Sprague-Grundy Theorem/sprague.cpp new file mode 100644 index 000000000..ccd6ddc94 --- /dev/null +++ b/Combinatorial Game Theory/Sprague-Grundy Theorem/sprague.cpp @@ -0,0 +1,117 @@ +#include +using namespace std; + +/* piles[] -> Array having the initial count of stones/coins + in each piles before the game has started. + n -> Number of piles + + Grundy[] -> Array having the Grundy Number corresponding to + the initial position of each piles in the game + + The piles[] and Grundy[] are having 0-based indexing*/ + +#define PLAYER1 1 +#define PLAYER2 2 + +// A Function to calculate Mex of all the values in that set +int calculateMex(unordered_set Set) +{ + int Mex = 0; + + while (Set.find(Mex) != Set.end()) + Mex++; + + return (Mex); +} + +// A function to Compute Grundy Number of 'n' +int calculateGrundy(int n, int Grundy[]) +{ + Grundy[0] = 0; + Grundy[1] = 1; + Grundy[2] = 2; + Grundy[3] = 3; + + if (Grundy[n] != -1) + return (Grundy[n]); + + unordered_set Set; // A Hash Table + + for (int i=1; i<=3; i++) + Set.insert (calculateGrundy (n-i, Grundy)); + + // Store the result + Grundy[n] = calculateMex (Set); + + return (Grundy[n]); +} + +// A function to declare the winner of the game +void declareWinner(int whoseTurn, int piles[], + int Grundy[], int n) +{ + int xorValue = Grundy[piles[0]]; + + for (int i=1; i<=n-1; i++) + xorValue = xorValue ^ Grundy[piles[i]]; + + if (xorValue != 0) + { + if (whoseTurn == PLAYER1) + printf("Player 1 will win\n"); + else + printf("Player 2 will win\n"); + } + else + { + if (whoseTurn == PLAYER1) + printf("Player 2 will win\n"); + else + printf("Player 1 will win\n"); + } + + return; +} + + +// Driver program to test above functions +int main() +{ + // Test Case 1 + int piles[] = {3, 4, 5}; + int n = sizeof(piles)/sizeof(piles[0]); + + // Find the maximum element + int maximum = *max_element(piles, piles + n); + + // An array to cache the sub-problems so that + // re-computation of same sub-problems is avoided + int Grundy[maximum + 1]; + memset(Grundy, -1, sizeof (Grundy)); + + // Calculate Grundy Value of piles[i] and store it + for (int i=0; i<=n-1; i++) + calculateGrundy(piles[i], Grundy); + + declareWinner(PLAYER1, piles, Grundy, n); + + /* Test Case 2 + int piles[] = {3, 8, 2}; + int n = sizeof(piles)/sizeof(piles[0]); + + + int maximum = *max_element (piles, piles + n); + + // An array to cache the sub-problems so that + // re-computation of same sub-problems is avoided + int Grundy [maximum + 1]; + memset(Grundy, -1, sizeof (Grundy)); + + // Calculate Grundy Value of piles[i] and store it + for (int i=0; i<=n-1; i++) + calculateGrundy(piles[i], Grundy); + + declareWinner(PLAYER2, piles, Grundy, n); */ + + return (0); +} diff --git a/Combinatorial Game Theory/Tic-Tac-Toe Optimal Move/tttoptmove.cpp b/Combinatorial Game Theory/Tic-Tac-Toe Optimal Move/tttoptmove.cpp new file mode 100644 index 000000000..c530639f0 --- /dev/null +++ b/Combinatorial Game Theory/Tic-Tac-Toe Optimal Move/tttoptmove.cpp @@ -0,0 +1,161 @@ +// C++ program to find the next optimal move for a player +#include +using namespace std; + +struct Move +{ + int row, col; +}; + +char player = 'x', opponent = 'o'; + +bool isMovesLeft(char board[3][3]) +{ + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + if (board[i][j] == '_') + return true; + return false; +} + +int evaluate(char b[3][3]) +{ + for (int row = 0; row < 3; row++) + { + if (b[row][0] == b[row][1] && + b[row][1] == b[row][2]) + { + if (b[row][0] == player) + return +10; + else if (b[row][0] == opponent) + return -10; + } + } + + for (int col = 0; col < 3; col++) + { + if (b[0][col] == b[1][col] && + b[1][col] == b[2][col]) + { + if (b[0][col] == player) + return +10; + + else if (b[0][col] == opponent) + return -10; + } + } + + if (b[0][0] == b[1][1] && b[1][1] == b[2][2]) + { + if (b[0][0] == player) + return +10; + else if (b[0][0] == opponent) + return -10; + } + + if (b[0][2] == b[1][1] && b[1][1] == b[2][0]) + { + if (b[0][2] == player) + return +10; + else if (b[0][2] == opponent) + return -10; + } + return 0; +} + +int minimax(char board[3][3], int depth, bool isMax) +{ + int score = evaluate(board); + + if (score == 10) + return score; + + if (score == -10) + return score; + + if (isMovesLeft(board) == false) + return 0; + + if (isMax) + { + int best = -1000; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + if (board[i][j] == '_') + { + board[i][j] = player; + + best = max(best, minimax(board, depth + 1, !isMax)); + board[i][j] = '_'; + } + } + } + return best; + } + + else + { + int best = 1000; + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + if (board[i][j] == '_') + { + board[i][j] = opponent; + best = min(best, minimax(board, depth + 1, !isMax)); + + board[i][j] = '_'; + } + } + } + return best; + } +} + +Move findBestMove(char board[3][3]) +{ + int bestVal = -1000; + Move bestMove; + bestMove.row = -1; + bestMove.col = -1; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + if (board[i][j] == '_') + { + board[i][j] = player; + int moveVal = minimax(board, 0, false); + board[i][j] = '_'; + if (moveVal > bestVal) + { + bestMove.row = i; + bestMove.col = j; + bestVal = moveVal; + } + } + } + } + + printf("The value of the best Move is : %d\n\n", bestVal); + return bestMove; +} +int main() +{ + char board[3][3] = + { + {'x', 'o', 'x'}, + {'o', 'o', 'x'}, + {'_', '_', '_'} + }; + + Move bestMove = findBestMove(board); + + printf("The Optimal Move is :\n"); + printf("ROW: %d COL: %d\n\n", bestMove.row, bestMove.col); + return 0; +} diff --git a/Combinatorial Game Theory/Zobrist Hashing/zobrist.cpp b/Combinatorial Game Theory/Zobrist Hashing/zobrist.cpp new file mode 100644 index 000000000..459fbaac6 --- /dev/null +++ b/Combinatorial Game Theory/Zobrist Hashing/zobrist.cpp @@ -0,0 +1,122 @@ + +// A program to illustrate Zobeist Hashing Algorithm +#include +using namespace std; + +unsigned long long int ZobristTable[8][8][12]; +mt19937 mt(01234567); + +// Generates a Randome number from 0 to 2^64-1 +unsigned long long int randomInt() +{ + uniform_int_distribution + dist(0, UINT64_MAX); + return dist(mt); +} + +// This function associates each piece with +// a number +int indexOf(char piece) +{ + if (piece=='P') + return 0; + if (piece=='N') + return 1; + if (piece=='B') + return 2; + if (piece=='R') + return 3; + if (piece=='Q') + return 4; + if (piece=='K') + return 5; + if (piece=='p') + return 6; + if (piece=='n') + return 7; + if (piece=='b') + return 8; + if (piece=='r') + return 9; + if (piece=='q') + return 10; + if (piece=='k') + return 11; + else + return -1; +} + +// Initializes the table +void initTable() +{ + for (int i = 0; i<8; i++) + for (int j = 0; j<8; j++) + for (int k = 0; k<12; k++) + ZobristTable[i][j][k] = randomInt(); +} + +// Computes the hash value of a given board +unsigned long long int computeHash(char board[8][9]) +{ + unsigned long long int h = 0; + for (int i = 0; i<8; i++) + { + for (int j = 0; j<8; j++) + { + if (board[i][j]!='-') + { + int piece = indexOf(board[i][j]); + h ^= ZobristTable[i][j][piece]; + } + } + } + return h; +} + +// Main Function +int main() +{ + // Uppercase letters are white pieces + // Lowercase letters are black pieces + char board[8][9] = + { + "---K----", + "-R----Q-", + "--------", + "-P----p-", + "-----p--", + "--------", + "p---b--q", + "----n--k" + }; + + initTable(); + + unsigned long long int hashValue = computeHash(board); + printf("The hash value is : %llu\n", hashValue); + + //Move the white king to the left + char piece = board[0][3]; + + board[0][3] = '-'; + hashValue ^= ZobristTable[0][3][indexOf(piece)]; + + board[0][2] = piece; + hashValue ^= ZobristTable[0][2][indexOf(piece)]; + + + printf("The new hash vlaue is : %llu\n", hashValue); + + // Undo the white king move + piece = board[0][2]; + + board[0][2] = '-'; + hashValue ^= ZobristTable[0][2][indexOf(piece)]; + + board[0][3] = piece; + hashValue ^= ZobristTable[0][3][indexOf(piece)]; + + printf("The old hash vlaue is : %llu\n", hashValue); + + return 0; +} diff --git a/Cryptography/CeaserCipher/C++/ceaser.cpp b/Cryptography/CeaserCipher/C++/ceaser.cpp new file mode 100644 index 000000000..4e5fb0665 --- /dev/null +++ b/Cryptography/CeaserCipher/C++/ceaser.cpp @@ -0,0 +1,29 @@ +//program to decrypt ceaser cipher +#include +#include +using namespace std; + +int main(){ + string s; + cin>>s; + //the most common letter in the english alphabet is e + map fre; + for(int i=0;ifirst)); +string fin; +for(int i=0;i + +// Number of vertices in the graph +#define V 4 + +/* Define Infinite as a large enough value. This value will be used + for vertices not connected to each other */ +#define INF 99999 + +// A function to print the solution matrix +void printSolution(int dist[][V]); + +// Solves the all-pairs shortest path problem using Floyd Warshall algorithm +void floydWarshall (int graph[][V]) +{ + /* dist[][] will be the output matrix that will finally have the shortest + distances between every pair of vertices */ + int dist[V][V], i, j, k; + + /* Initialize the solution matrix same as input graph matrix. Or + we can say the initial values of shortest distances are based + on shortest paths considering no intermediate vertex. */ + for (i = 0; i < V; i++) + for (j = 0; j < V; j++) + dist[i][j] = graph[i][j]; + + /* Add all vertices one by one to the set of intermediate vertices. + ---> Before start of an iteration, we have shortest distances between all + pairs of vertices such that the shortest distances consider only the + vertices in set {0, 1, 2, .. k-1} as intermediate vertices. + ----> After the end of an iteration, vertex no. k is added to the set of + intermediate vertices and the set becomes {0, 1, 2, .. k} */ + for (k = 0; k < V; k++) + { + // Pick all vertices as source one by one + for (i = 0; i < V; i++) + { + // Pick all vertices as destination for the + // above picked source + for (j = 0; j < V; j++) + { + // If vertex k is on the shortest path from + // i to j, then update the value of dist[i][j] + if (dist[i][k] + dist[k][j] < dist[i][j]) + dist[i][j] = dist[i][k] + dist[k][j]; + } + } + } + + // Print the shortest distance matrix + printSolution(dist); +} + +/* A utility function to print solution */ +void printSolution(int dist[][V]) +{ + printf ("The following matrix shows the shortest distances" + " between every pair of vertices \n"); + for (int i = 0; i < V; i++) + { + for (int j = 0; j < V; j++) + { + if (dist[i][j] == INF) + printf("%7s", "INF"); + else + printf ("%7d", dist[i][j]); + } + printf("\n"); + } +} + + diff --git a/Dynamic Programming/Binomial Coefficient/C/binCoeff.c b/Dynamic Programming/Binomial Coefficient/C/binCoeff.c new file mode 100644 index 000000000..e45e9e9bc --- /dev/null +++ b/Dynamic Programming/Binomial Coefficient/C/binCoeff.c @@ -0,0 +1,34 @@ +#include + +int min(int a, int b); + +int binomialCoeff(int n, int k) +{ + int C[n + 1][k + 1]; + int i, j; + for (i = 0; i <= n; i++) + { + for (j = 0; j <= min(i, k); j++) + { + if (j == 0 || j == i) + C[i][j] = 1; + + else + C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; + } + } + + return C[n][k]; +} + +int min(int a, int b) +{ + return (a < b) ? a : b; +} + +int main() +{ + int n = 5, k = 2; + printf("Value of C(%d, %d) is %d ", n, k, binomialCoeff(n, k)); + return 0; +} diff --git a/Dynamic Programming/Binomial Coefficient/Java/BinCoeff.java b/Dynamic Programming/Binomial Coefficient/Java/BinCoeff.java new file mode 100644 index 000000000..f3d0b1ce0 --- /dev/null +++ b/Dynamic Programming/Binomial Coefficient/Java/BinCoeff.java @@ -0,0 +1,28 @@ +class BinCoeff { + static int binomialCoeff(int n, int k) { + int C[][] = new int[n + 1][k + 1]; + int i, j; + + for (i = 0; i <= n; i++) { + for (j = 0; j <= min(i, k); j++) { + + if (j == 0 || j == i) + C[i][j] = 1; + + else + C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; + } + } + + return C[n][k]; + } + + static int min(int a, int b) { + return (a < b) ? a : b; + } + + public static void main(String args[]) { + int n = 5, k = 2; + System.out.println("Value of C(" + n + "," + k + ") is " + binomialCoeff(n, k)); + } +} diff --git a/Dynamic Programming/Binomial Coefficient/Python/binCoeff.py b/Dynamic Programming/Binomial Coefficient/Python/binCoeff.py new file mode 100644 index 000000000..2ed1dc823 --- /dev/null +++ b/Dynamic Programming/Binomial Coefficient/Python/binCoeff.py @@ -0,0 +1,16 @@ +def binomialCoef(n, k): + C = [[0 for x in range(k+1)] for x in range(n+1)] + for i in range(n+1): + for j in range(min(i, k)+1): + + if j == 0 or j == i: + C[i][j] = 1 + + else: + C[i][j] = C[i-1][j-1] + C[i-1][j] + + return C[n][k] + +n = 5 +k = 2 +print("Value of C[" + str(n) + "][" + str(k) + "] is " + str(binomialCoef(n,k))) diff --git a/Dynamic Programming/Boolean Parenthesization Problem/cpp/boolean_parenthesization.cpp b/Dynamic Programming/Boolean Parenthesization Problem/cpp/boolean_parenthesization.cpp new file mode 100644 index 000000000..fda29a3bc --- /dev/null +++ b/Dynamic Programming/Boolean Parenthesization Problem/cpp/boolean_parenthesization.cpp @@ -0,0 +1,72 @@ +//This algorithm is for counting the number of ways we can +// parenthesize the expression so that the value of expression evaluates to true. +#include +#include +using namespace std; + +// Returns count of all possible parenthesizations that lead to +// result true for a boolean expression with symbols like true +// and false and operators like &, | and ^ filled between symbols +int countParenth(char symb[], char oper[], int n) +{ + int F[n][n], T[n][n]; + + // All diagonal entries in T[i][i] are 1 if symbol[i] + // is T (true). Similarly, all F[i][i] entries are 1 if + // symbol[i] is F (False) + for (int i = 0; i < n; i++) + { + F[i][i] = (symb[i] == 'F')? 1: 0; + T[i][i] = (symb[i] == 'T')? 1: 0; + } + + // Now fill T[i][i+1], T[i][i+2], T[i][i+3]... in order + // And F[i][i+1], F[i][i+2], F[i][i+3]... in order + for (int gap=1; gap +using namespace std; + +int lcs3(vector &a, vector &b, vector &c) { + int n = a.size(); int m = b.size(); int p = c.size(); + vector < vector < vector > > dp(n + 1, vector < vector > (m + 1, vector (p + 1))); + for (int i = 0; i < n + 1; ++i) { + for (int j = 0; j < m + 1; ++j) { + for (int k = 0; k < p + 1; ++k){ + if(i == 0 || j == 0 || k == 0) { + dp[i][j][k] = 0; + } + else if(a[i - 1] == b[j - 1] && a[i - 1] == c[k - 1]) { + dp[i][j][k] = 1 + dp[i - 1][j - 1][k - 1]; + } + else { + dp[i][j][k] = max(dp[i][j - 1][k], max(dp[i - 1][j][k], dp[i][j][k - 1])); + } + } + } + } + return dp[n][m][p]; +} + +int main() { + size_t an; cin >> an; vector a(an); + for (size_t i = 0; i < an; i++) { + cin >> a[i]; + } + size_t bn; cin >> bn; vector b(bn); + for (size_t i = 0; i < bn; i++) { + cin >> b[i]; + } + size_t cn; cin >> cn; vector c(cn); + for (size_t i = 0; i < cn; i++) { + cin >> c[i]; + } + cout << lcs3(a, b, c) << endl; +} diff --git a/Dynamic Programming/Common Subsequence 3/python/longest_common_subsequence_3.py b/Dynamic Programming/Common Subsequence 3/python/longest_common_subsequence_3.py new file mode 100644 index 000000000..44f1e58e8 --- /dev/null +++ b/Dynamic Programming/Common Subsequence 3/python/longest_common_subsequence_3.py @@ -0,0 +1,18 @@ +# Longest Common Sequence of 3 Sequences +def lcs3(a, b, c): + n, m, p = len(a), len(b), len(c) + dp = [[[0]*(p + 1) for i in xrange(m + 1)] for j in xrange(n + 1)] + for i in xrange(n + 1): + for j in xrange(m + 1): + for k in xrange(p + 1): + if i == 0 or j == 0 or k == 0: + dp[i][j][k] = 0 + elif a[i - 1] == b[j - 1] and a[i - 1] == c[k - 1]: + dp[i][j][k] = 1 + dp[i - 1][j - 1][k - 1] + else: + dp[i][j][k] = max(dp[i][j][k - 1], max(dp[i][j - 1][k], dp[i - 1][j][k])) + return dp[n][m][p] + +if __name__ == '__main__': + a, b, c = raw_input().split() + print(lcs3(a, b, c)) \ No newline at end of file diff --git a/Dynamic Programming/Create Maximum Cost List/README.md b/Dynamic Programming/Create Maximum Cost List/README.md new file mode 100644 index 000000000..d409345a1 --- /dev/null +++ b/Dynamic Programming/Create Maximum Cost List/README.md @@ -0,0 +1,21 @@ +There are 2 lists X and Y with same number of elements N. There exist a relation between these lists: + + 1 <= ith element of X <= ith element of Y + +And the cost of a list defines as: + + Σ|𝑿𝒊−𝑿𝒊−𝟏| + +This program finding out the maximum possible cost of list X. + +**Input Format and Sample Input** + +Given a list Y, +Y = [5, 6, 8, 13, 9] + +**Output Format and Sample Output** + +The maximum possible cost, 34 + + + diff --git a/Dynamic Programming/Create Maximum Cost List/solution.py b/Dynamic Programming/Create Maximum Cost List/solution.py new file mode 100644 index 000000000..f78becc86 --- /dev/null +++ b/Dynamic Programming/Create Maximum Cost List/solution.py @@ -0,0 +1,32 @@ +''' + @author: Sevval MEHDER + + Filling one cell: O(1) + Filling all cells: O(2xn) = O(n) + +''' + +def find_maximum_cost(Y): + values = [[0 for _ in range(2)] for _ in range(len(Y))] + + + # Go on with adding these 2 options + i = 1 + while i < len(Y): + # Put these two options + values[i][0] = max(values[i - 1][0], values[i - 1][1] + Y[i - 1] - 1) + values[i][1] = max(values[i - 1][1] + abs(Y[i] - Y[i - 1]), values[i - 1][0] + Y[i] - 1) + i += 1 + #print(values) + + return max(values[len(Y) - 1][0], values[len(Y) - 1][1]) + + +def main(): + Y = [5, 6, 8, 13, 9] + cost = find_maximum_cost(Y) + print(cost) + # Output: 34 + + +main() diff --git a/Dynamic Programming/Editing Distance/cpp/editing_distance.cpp b/Dynamic Programming/Editing Distance/cpp/editing_distance.cpp new file mode 100644 index 000000000..8e3bc7414 --- /dev/null +++ b/Dynamic Programming/Editing Distance/cpp/editing_distance.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +int edit_distance(const string &str1, const string &str2) { + int m = str1.size(); int n = str2.size(); + vector < vector > dp(m + 1, vector (n + 1)); + for (int i = 0; i < m + 1; i++) { + for (int j = 0; j < n + 1; ++j) { + if (i == 0) { + dp[i][j] = j; + } + else if(j == 0) { + dp[i][j] = i; + } + else if(str1[i - 1] == str2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } + else { + dp[i][j] = 1 + min(dp[i][j - 1], min(dp[i - 1][j - 1], dp[i - 1][j])); + } + } + } + return dp[m][n]; +} + +int main() { + string str1; string str2; cin >> str1 >> str2; + cout << edit_distance(str1, str2) << endl; + return 0; +} diff --git a/Dynamic Programming/Editing Distance/python/editing_distance.py b/Dynamic Programming/Editing Distance/python/editing_distance.py new file mode 100644 index 000000000..4846928a3 --- /dev/null +++ b/Dynamic Programming/Editing Distance/python/editing_distance.py @@ -0,0 +1,18 @@ +# Uses python2 +def edit_distance(s, t): + m, n = len(s), len(t) + dp = [[0]*(n + 1) for i in xrange(m + 1)] + for i in xrange(m + 1): + for j in xrange(n + 1): + if i == 0: + dp[i][j] = j + elif j == 0: + dp[i][j] = i + elif s[i - 1] == t[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + else: + dp[i][j] = 1 + min(dp[i - 1][j], min(dp[i][j - 1], dp[i - 1][j - 1])) + return dp[m][n] + +if __name__ == "__main__": + print(edit_distance(raw_input(), raw_input())) diff --git a/Dynamic Programming/LCSDP/Java/LCS.java b/Dynamic Programming/LCSDP/Java/LCS.java new file mode 100644 index 000000000..adae36bec --- /dev/null +++ b/Dynamic Programming/LCSDP/Java/LCS.java @@ -0,0 +1,46 @@ +import java.util.Arrays; +import java.lang.Math; + +// Function to find length of longest common subsequence between 2 strings. +// Recursive, TopDown & BottomUp approaches implemented. + +class LCS{ + public static void main(String[] args){ + String s1 = "Vishal"; + String s2 = "Vashist"; + int m = s1.length(), n = s2.length(); + int[][] TP = new int[m+1][n+1]; + for(int i=0;i +using namespace std; + +int lps(string s){ + int n=s.length(); + int lps[n][n]; + // length 1 + for(int i=0 ; i +#include + +// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n +int MatrixChainOrder(int p[], int n) +{ + + /* For simplicity of the program, one extra row and one + extra column are allocated in m[][]. 0th row and 0th + column of m[][] are not used */ + int m[n][n]; + + int i, j, k, L, q; + + /* m[i,j] = Minimum number of scalar multiplications needed + to compute the matrix A[i]A[i+1]...A[j] = A[i..j] where + dimension of A[i] is p[i-1] x p[i] */ + + // cost is zero when multiplying one matrix. + for (i=1; i +using namespace std; +map,int>mp; +//global declaration of variables +int t=0,x,y,n,k; +void check(int x,int y,int x2,int y2){ +while(x<=n && x>0 && y<=n && y>0 && mp[{x,y}]==0){ +x+=x2; +y+=y2; +t++; +}} + +//driver program + +int main(){ +cin>>n>>k; +int x1,y1; +cin>>x>>y; + +//we are making pair so as to mark the position of obstacles (here i am marking its position say mp[{x,y}]=1 so as to recognize the position of obsatcles +//if there is obstacle present by the way i am checking this in checkfunction +//we can move to the consecutive location until no obstacles present + +while(k--){ +cin>>x1>>y1; +mp[{x1,y1}]=1; +} + +//these are the positions the queen can move up,down,left,right,and the 4 diagonals from its current positions say(x,y) +check(x+1,y,1,0);//right direction +check(x-1,y,-1,0);//left direction +check(x,y+1,0,1);//up direction +check(x,y-1,0,-1);//down direction +//the adjacent 4 diagonals directions +check(x-1,y-1,-1,-1); +check(x+1,y+1,1,1); +check(x+1,y-1,1,-1); +check(x-1,y+1,-1,1); +cout< +using namespace std; + +/* Function to get the nth ugly number*/ +unsigned getNthUglyNo(unsigned n) +{ + unsigned ugly[n]; + unsigned i2 = 0, i3 = 0, i5 = 0; + unsigned next_multiple_of_2 = 2; + unsigned next_multiple_of_3 = 3; + unsigned next_multiple_of_5 = 5; + unsigned next_ugly_no = 1; + + ugly[0] = 1; + for (int i=1; i> n; + cout << getNthUglyNo(n); + return 0; +} diff --git a/Dynamic Programming/WeightedJobScheduling/README.md b/Dynamic Programming/WeightedJobScheduling/README.md new file mode 100644 index 000000000..ecb2e2dac --- /dev/null +++ b/Dynamic Programming/WeightedJobScheduling/README.md @@ -0,0 +1,8 @@ +Problem: +Given N jobs where every job is represented by following three elements of it. + + Start Time + Finish Time + Profit or Value Associated + +Find the maximum profit subset of jobs such that no two jobs in the subset overlap. \ No newline at end of file diff --git a/Dynamic Programming/WeightedJobScheduling/cpp/weighted_job_scheduling.cpp b/Dynamic Programming/WeightedJobScheduling/cpp/weighted_job_scheduling.cpp new file mode 100644 index 000000000..dfaf04676 --- /dev/null +++ b/Dynamic Programming/WeightedJobScheduling/cpp/weighted_job_scheduling.cpp @@ -0,0 +1,65 @@ +#include +using namespace std; + +struct Job +{ + int start, finish, profit; +}jobs[100005]; + + +bool comp(Job a, Job b) +{ + return a.finish < b.finish; +} + +int binarySearch(int index) +{ + int l= 0, h = index - 1; + int ans = -1; + while (l<=h) + { + int m = (l+h)/2; + if (jobs[m].finish <= jobs[index].start) + { + ans = m; + l = m+1; + } + else + h = m-1; + } + return ans; +} + +//Main function which computes optimal profit +int weighted_job(int n) +{ + + sort(jobs, jobs+n, comp); + + int dp[n]; + + dp[0] = jobs[0].profit; + + for (int i=1; i>n; + //Enter the jobs start time,finish time and profit of the job. + for(int i = 0;i>jobs[i].start>>jobs[i].finish>>jobs[i].profit; + } + cout<<"Maximum profit will be "< +using namespace std; +int main(){ +long n,m; +cin>>n>>m; +long T[251][251]; +long w; +vectora; +for(int k=0;k>w; + a.push_back(w); +} +a.push_back(0); +sort(a.begin(),a.end()); +int d=a.size(); +for(int i=0;ij) + T[i][j]=T[i-1][j]; + else{ + T[i][j]=T[i-1][j]+T[i][j-a[i]]; + } + } + } +} +cout< +using namespace std; +long getWaysHelper(int, vector,int); + +//Recurrsive Solution +//TC = O(2^m) where m is the size of coins vector +//SC = O(m) is the Recurrsive depth +long getWaysRecc(int n, vector coins) { + return getWaysHelper(n,coins,0); +} +long getWaysHelper(int n, vector coins,int i){ + if(n ==0) + return 1; + else if(n < 0) + return 0; + else{ + long change = 0; + for(int index = i;index= c[i] + memo[i-1][j] + memo[i][j-c[i]] if i > 0 and j >= c[i] + } +*/ + +//DP solution +// TC = O(m*n) where m = size of coins vector +// SC = O(m*n) +long getWays(long n, vector c) { + long memo[c.size()][n+1]; + for(int i=0;i < c.size(); i++){ + for(int j=0; j < n+1 ; j++){ + if(j==0){//no. of ways of forming change for 0 + memo[i][j] = 1; + } + else{ + long x,y; + //if include coin[j] + x = j - c[i]>=0 ? memo[i][j-c[i]] : 0; + //if i exclude coin[j] + y = i > 0 ? memo[i-1][j]: 0 ; + memo[i][j] = x + y; + } + } + } + return memo[c.size()-1][n]; +} + + + +int main(){ + vector c = {1,2,3}; + int n = 4; + cout< + +using namespace std; + +int get_change(int m, vector c) { + vector s(m + 1, m); + int n = c.size(); + s[0] = 0; + for (int i = 1; i < m + 1; ++i) { + for (int j = 0; j < n; ++j) { + if(i >= c[j] && s[i - c[j]] + 1 < s[i]) { + s[i] = s[i - c[j]] + 1; + } + } + } + return s[m]; +} + +int main() { + int m, n; cin >> m >> n; // m is the value needed, n is the size of coins array + vector c(n); + for (int i = 0; i < n; ++i) { + cin >> c[i]; + } + cout << get_change(m, c); +} diff --git a/Dynamic Programming/coin change/java/coin_change.java b/Dynamic Programming/coin change/java/coin_change.java new file mode 100644 index 000000000..08a065269 --- /dev/null +++ b/Dynamic Programming/coin change/java/coin_change.java @@ -0,0 +1,35 @@ +/* +Input : - n : number of units + m : number of coin types + m space seperated integers respective values of coin type + +Output:- Lonf=g Integer denoting number of ways we can get a sum of n from given infinte supply of m coins +*/ +import java.io.*; +import java.util.*; + +public class Solution { + + public static void main(String[] args) { + Scanner s=new Scanner(System.in); + int n=s.nextInt(); + int m=s.nextInt(); + int[] c=new int[m]; + for(int i=0;i=c[i]: + r[j]+=r[j-c[i]] + return r[n] +nm = input().split() +n = int(nm[0]) +m = int(nm[1]) +c = list(map(int, input().rstrip().split())) +print(getWays(n,c)) diff --git a/Dynamic Programming/coin change/python/min_coin_change_value.py b/Dynamic Programming/coin change/python/min_coin_change_value.py new file mode 100644 index 000000000..dcb9e6dd5 --- /dev/null +++ b/Dynamic Programming/coin change/python/min_coin_change_value.py @@ -0,0 +1,16 @@ +# Minimum coins needed for a value +def get_change(m, c): + n = len(c) + s = [m]*(m + 1) + s[0] = 0 + for i in xrange(1, m + 1): + for j in xrange(n): + if i >= c[j] and s[i - c[j]] + 1 < s[i]: + s[i] = s[i - c[j]] + 1 + return s[m] + +if __name__ == '__main__': + m = int(raw_input()) + # c = [1, 3, 4] + c = map(int, raw_input().split()) + print(get_change(m, c)) \ No newline at end of file diff --git a/Dynamic Programming/common sub sequence/cpp/LCS.cpp b/Dynamic Programming/common sub sequence/cpp/LCS.cpp new file mode 100644 index 000000000..569d18d55 --- /dev/null +++ b/Dynamic Programming/common sub sequence/cpp/LCS.cpp @@ -0,0 +1,150 @@ +#include +#include +#include +using namespace std; + + +void strrev(char c[]) +{ + int i = 0, j = strlen(c); + + while(i < j/2) + { + char t = c[i]; + c[i] = c[j - i - 1]; + c[j - i - 1] = t; + i++; + } + +} + +void PrintPath(int **Diag, char a[], char c[], int i, int j) +{ + + static int k = 0; + if(i == 0 || j == 0) + return; + + if(Diag[i][j] == 1) + PrintPath(Diag, a, c, i, j-1); + + else if(Diag[i][j] == 2) + PrintPath(Diag, a, c, i-1, j); + + else if(Diag[i][j] == 0) + { + c[k++] = a[i]; + c[k] = '\0'; + + PrintPath(Diag, a, c, i-1, j-1); + } + + else + return; +} + + +void LongestCommonSubsequence(char a[], char b[], int alen, int blen) +{ + int **LCS, **Diag; + + LCS = new int*[alen + 1]; + Diag = new int*[alen]; + + for (int i = 0; i < alen; ++i) + LCS[i] = new int [blen + 1]; + + for (int i = 0; i < alen; ++i) + Diag[i] = new int [blen]; + +//--------giving value -1 to diag ----------------- + for (int i = 0; i < alen; ++i) + for (int j = 0; j < blen; ++j) + Diag[i][j] = -1; + +//--------------------Giving value 0 to LCS for i = 0 and j = 0---------------- + for (int i = 0; i < alen; ++i) + LCS[i][0] = 0; + + for (int i = 0; i < blen; ++i) + LCS[0][i] = 0; + + +//------------------Computing LCS matrix----------------------- + for (int i = 1; i < alen; ++i) + { + for (int j = 1; j < blen; ++j) + { + if(a[i] == b[j]) + { + LCS[i][j] = 1 + LCS[i-1][j-1]; + Diag[i][j] = 0; //Move diagonally backwards + } + + else + { + //---FINDING MAX ------------- + + if( LCS[i][j-1] > LCS[i-1][j] ) + { + LCS[i][j] = LCS[i][j-1] ; + Diag[i][j] = 1; //Move horizantally backwards + } + + else + { + LCS[i][j] = LCS[i-1][j]; //Move vertically backwards + Diag[i][j] = 2; + } + } + } + } + + +// cout<>c>>d; + + a[0] = b[0] = '0'; + a[1] = b[1] = '\0'; + + strcat(a,c); + strcat(b,d); + + int alen = strlen(a), blen = strlen(b); + + LongestCommonSubsequence(a, b, alen, blen); + + + +} \ No newline at end of file diff --git a/Dynamic Programming/common sub sequence/perl-6 b/Dynamic Programming/common sub sequence/perl-6 new file mode 100644 index 000000000..d49ae092d --- /dev/null +++ b/Dynamic Programming/common sub sequence/perl-6 @@ -0,0 +1,33 @@ +// perl 6 code + +sub lcs(Str $xstr, Str $ystr) { + my ($xlen, $ylen) = ($xstr, $ystr)>>.chars; + my @lengths = map {[(0) xx ($ylen+1)]}, 0..$xlen; + + for $xstr.comb.kv -> $i, $x { + for $ystr.comb.kv -> $j, $y { + @lengths[$i+1][$j+1] = $x eq $y ?? @lengths[$i][$j]+1 !! (@lengths[$i+1][$j], @lengths[$i][$j+1]).max; + } + } + + my @x = $xstr.comb; + my ($x, $y) = ($xlen, $ylen); + my $result = ""; + while $x != 0 && $y != 0 { + if @lengths[$x][$y] == @lengths[$x-1][$y] { + $x--; + } + elsif @lengths[$x][$y] == @lengths[$x][$y-1] { + $y--; + } + else { + $result = @x[$x-1] ~ $result; + $x--; + $y--; + } + } + + return $result; +} + +say lcs("thisisatest", "testing123testing"); diff --git a/Dynamic Programming/fibo.cpp b/Dynamic Programming/fibo.cpp new file mode 100644 index 000000000..1d712e24d --- /dev/null +++ b/Dynamic Programming/fibo.cpp @@ -0,0 +1,22 @@ +#include +using namespace std; + +int Fib[10000]; + +int main() { + int n; + cin >> n; + + //0th and 1st number of the series are 0 and 1 + Fib[0] = 0; + Fib[1] = 1; + + //Fibonacci using DP + for(int i = 2; i <= n; i++) { + Fib[i] = Fib[i - 1] + Fib[i - 2]; + } + + cout << Fib[n] << endl; + + return 0; +} \ No newline at end of file diff --git a/Dynamic Programming/fibonacci/cpp/fibonacci.cpp b/Dynamic Programming/fibonacci/cpp/fibonacci.cpp new file mode 100644 index 000000000..4c36ecef0 --- /dev/null +++ b/Dynamic Programming/fibonacci/cpp/fibonacci.cpp @@ -0,0 +1,20 @@ +#include +using namespace std; + +int fibonacci(int n) +{ + int fib[n]; + int i; + fib[0] = 0; + fib[1] = 1; + for (i = 2; i <= n; i++) + fib[i] = fib[i-1] + fib[i-2]; + return fib[n]; +} + +int main () +{ + int n = 9; + cout< +using namespace std; +#define N 100 +#define W 100 +#define K 100 + +int dp[N][W][K]; +int solve(int profit[], + int weight[], + int n, int max_W, + int max_E) +{ + + // for each element given + for (int i = 1; i <= n; i++) { + + // For each possible + // weight value + for (int j = 1; j <= max_W; j++) { + + // For each case where + // the total elements are + // less than the constraint + for (int k = 1; k <= max_E; k++) { + + // To ensure that we dont + // go out of the array + if (j >= weight[i]) { + + dp[i][j][k] + = max( + dp[i - 1][j][k], + dp[i - 1] + [j - weight[i]] + [k - 1] + + profit[i]); + } + else { + dp[i][j][k] + = dp[i - 1][j][k]; + } + } + } + } + + return dp[n][max_W][max_E]; +} + +// Driver Code +int main() +{ + + memset(dp, 0, sizeof(dp)); + + int n = 5; + int profit[] = { 2, 7, 1, 5, 3 }; + int weight[] = { 2, 5, 2, 3, 4 }; + int max_weight = 8; + int max_element = 2; + cout << solve(profit, + weight, n, + max_weight, + max_element) + << "\n"; + + return 0; +} diff --git a/Dynamic Programming/knapsack/java/Knapsack.java b/Dynamic Programming/knapsack/java/Knapsack.java new file mode 100644 index 000000000..badbe3828 --- /dev/null +++ b/Dynamic Programming/knapsack/java/Knapsack.java @@ -0,0 +1,27 @@ + +public class Knapsack { + + public int knapSack(int weights[], int costs[], int capacity) { + int numberOfWeights = weights.length; + int best[][] = new int[numberOfWeights + 1][capacity + 1]; + + // calculate the best array + for (int i = 0; i <= numberOfWeights; i++) { + for (int weight = 0; weight <= capacity; weight++) { + + if (i == 0 || weight == 0) { + best[i][weight] = 0; + + } else if (weights[i - 1] <= weight) { + best[i][weight] = Math.max(best[i - 1][weight], + costs[i - 1] + best[i - 1][weight - weights[i - 1]]); + + } else { + best[i][weight] = best[i - 1][weight]; + } + } + } + + return best[numberOfWeights][capacity]; + } +} diff --git a/Dynamic Programming/knapsack/java/UnboundedKnapsack.java b/Dynamic Programming/knapsack/java/UnboundedKnapsack.java new file mode 100644 index 000000000..f3bd72805 --- /dev/null +++ b/Dynamic Programming/knapsack/java/UnboundedKnapsack.java @@ -0,0 +1,33 @@ +import java.lang.Math; + +class UnboundedKnapsack { + + static int knapSack( + int W, int wt[], + int val[], int n) + { + // Base Case + if (n == 0 || W == 0) + return 0; + + if (wt[n - 1] > W) + return knapSack(W, wt, val, n - 1); + + else + return Math.max( + val[n - 1] + knapSack(W - wt[n - 1], + wt, val, n), + knapSack(W, wt, val, n - 1)); + } + + // Driver program to test + // above function + public static void main(String args[]) + { + int val[] = new int[] { 60, 100, 120 }; + int wt[] = new int[] { 10, 20, 30 }; + int W = 50; + int n = val.length; + System.out.println(knapSack(W, wt, val, n)); + } +} diff --git a/Dynamic Programming/max_subarray/java/max_subarry.java b/Dynamic Programming/max_subarray/java/max_subarry.java new file mode 100644 index 000000000..6372b9a46 --- /dev/null +++ b/Dynamic Programming/max_subarray/java/max_subarry.java @@ -0,0 +1,51 @@ +/* +Input :- No of test cases + No of integers + Integers separated by space + +Output - Maximum Contiguous Subarray +*/ + +import java.io.*; +import java.util.*; + +public class Solution { + + public static void main(String[] args) { + Scanner s=new Scanner(System.in); + int tc=s.nextInt(); + while(tc-->0) + { + int n=s.nextInt(); + int[] a=new int[n]; + for(int i=0;i=0&&a[i]>0) + {ans1+=a[i]; + i--; + } + } + System.out.println(max1+" "+ans1); + } + /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */ + } +} diff --git a/Dynamic Programming/max_subarray_sum.cpp b/Dynamic Programming/max_subarray_sum.cpp new file mode 100644 index 000000000..ba3db141d --- /dev/null +++ b/Dynamic Programming/max_subarray_sum.cpp @@ -0,0 +1,44 @@ + +//Size of The Subarray With Maximum Sum +//An array is given, find length of the subarray having maximum sum. + +// C++ program to print length of the largest +// contiguous array sum +#include +#include +using namespace std; + +int maxSubArraySum(int a[], int size) +{ + int max_so_far = INT_MIN, max_ending_here = 0, + start =0, end = 0, s=0; + + for (int i=0; i< size; i++ ) + { + max_ending_here += a[i]; + + if (max_so_far < max_ending_here) + { + max_so_far = max_ending_here; + start = s; + end = i; + } + + if (max_ending_here < 0) + { + max_ending_here = 0; + s = i + 1; + } + } + + return (end - start + 1); +} + +/*Driver program to test maxSubArraySum*/ +int main() +{ + int a[] = {-2, -3, 4, -1, -2, 1, 5, -3}; + int n = sizeof(a)/sizeof(a[0]); + cout << maxSubArraySum(a, n); + return 0; +} diff --git a/Dynamic Programming/minimized cost of binary search tree/Description.md b/Dynamic Programming/minimized cost of binary search tree/Description.md new file mode 100644 index 000000000..472f3a74f --- /dev/null +++ b/Dynamic Programming/minimized cost of binary search tree/Description.md @@ -0,0 +1 @@ +Consider a list of n ordered pairs of integers. These records need to be arranged in a binary search tree according to the key value of the first coordinate. The specific structure of the tree needs to be determined by you, such that the sum of the product of the depth of each node together with the second coordinate of that node is minimized. For simplicity, you may assume no duplication of values among the first coordinates. This problem should be solved using dynamic programming. diff --git a/Dynamic Programming/minimized cost of binary search tree/solution.cpp b/Dynamic Programming/minimized cost of binary search tree/solution.cpp new file mode 100644 index 000000000..70e780c4a --- /dev/null +++ b/Dynamic Programming/minimized cost of binary search tree/solution.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#define ll long long + +using namespace std; +vector level[10000]; +void print(vector > p,ll i,ll j,ll* a,ll l) //print function +{ + if(i>j) return ; + + print(p,i,p[i][j]-1,a,l+1); //recursion go to left side + level[l].push_back(a[p[i][j]]); + print(p,p[i][j]+1,j,a,l+1); //recursion go to right side +} + +int main() +{ + ll n; + cin >>n; + pair a[n]; + ll b[n]; + for(ll i=0; i> a[i].first >>a[i].second; + } + sort(a,a+n); + for(ll i=0; i > p; + + for(ll i=0; i t; + for(ll j=0; j=i; m--) + { + ll temp1=0,temp2=0; + if(i=temp) + { + min=temp; + p[i][j]=m; + } + } + dp[i][j]=min; //dp value set as minimum value + i++; + } + } + cout<<"Minimum Cost : "<::const_iterator j = level[i].begin(); j != level[i].end(); ++j) + { + std::cout << *j <<" "; + } + cout< sum) + return isSubsetSum(set, n - 1, sum); + return isSubsetSum(set, n - 1, sum) + || isSubsetSum(set, n - 1, sum - set[n - 1]); + } + + /* Driver program to test above function */ + public static void main(String args[]) + { + int set[] = { 3, 34, 4, 12, 5, 2 }; + int sum = 9; + int n = set.length; + if (isSubsetSum(set, n, sum) == true) + System.out.println("Subset found" + + " with given sum"); + else + System.out.println("No subset with" + + " given sum"); + } +} diff --git a/Dynamic Programming/sub set sum/python/subSetSum.py b/Dynamic Programming/sub set sum/python/subSetSum.py new file mode 100644 index 000000000..bf52466d5 --- /dev/null +++ b/Dynamic Programming/sub set sum/python/subSetSum.py @@ -0,0 +1,28 @@ +def isSubsetSum(set,n, sum) : + + # Base Cases + if (sum == 0) : + return True + if (n == 0 and sum != 0) : + return False + + # If last element is greater than + # sum, then ignore it + if (set[n - 1] > sum) : + return isSubsetSum(set, n - 1, sum) + + # else, check if sum can be obtained + # by any of the following + # (a) including the last element + # (b) excluding the last element + return isSubsetSum(set, n-1, sum) or isSubsetSum(set, n-1, sum-set[n-1]) + + +# Test case +set = [3, 34, 4, 12, 5, 2] +sum = 100 +n = len(set) +if (isSubsetSum(set, n, sum) == True) : + print("Found a subset with given sum") +else : + print("No subset with given sum") \ No newline at end of file diff --git a/Graphs/A star pathfinding algorithm/Astar.py b/Graphs/A star pathfinding algorithm/Astar.py new file mode 100644 index 000000000..ee15064ee --- /dev/null +++ b/Graphs/A star pathfinding algorithm/Astar.py @@ -0,0 +1,130 @@ +#In computer science, A* (pronounced as "A star") is a computer algorithm that is widely used in pathfinding and graph +# traversal, which is the process of finding a path between multiple points, called "nodes". It enjoys widespread use due +#to its performance and accuracy. However, in practical travel-routing systems, it is generally outperformed by algorithms +# which can pre-process the graph to attain better performance, although other work has found A* to be superior to other +#approaches. + +#This algorithm is widely used in the field game development to approximate the shortest path on a map +#It is similar to Dijkstra’s Algorithm in the sense that the main objective of both algorithms is to find the shortest path +# but it runs much quicker than Dijkstra’s Algorithm + +class Node(): + """A node class for A* Pathfinding""" + + def __init__(self, parent=None, position=None): + self.parent = parent + self.position = position + + self.g = 0 + self.h = 0 + self.f = 0 + + def __eq__(self, other): + return self.position == other.position + + +def astar(maze, start, end): + """Returns a list of tuples as a path from the given start to the given end in the given maze""" + + # Create start and end node + start_node = Node(None, start) + start_node.g = start_node.h = start_node.f = 0 + end_node = Node(None, end) + end_node.g = end_node.h = end_node.f = 0 + + # Initialize both open and closed list + open_list = [] + closed_list = [] + + # Add the start node + open_list.append(start_node) + + # Loop until you find the end + while len(open_list) > 0: + + # Get the current node + current_node = open_list[0] + current_index = 0 + for index, item in enumerate(open_list): + if item.f < current_node.f: + current_node = item + current_index = index + + # Pop current off open list, add to closed list + open_list.pop(current_index) + closed_list.append(current_node) + + # Found the goal + if current_node == end_node: + path = [] + current = current_node + while current is not None: + path.append(current.position) + current = current.parent + return path[::-1] # Return reversed path + + # Generate children + children = [] + for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares + + # Get node position + node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1]) + + # Make sure within range + if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0: + continue + + # Make sure walkable terrain + if maze[node_position[0]][node_position[1]] != 0: + continue + + # Create new node + new_node = Node(current_node, node_position) + + # Append + children.append(new_node) + + # Loop through children + for child in children: + + # Child is on the closed list + for closed_child in closed_list: + if child == closed_child: + continue + + # Create the f, g, and h values + child.g = current_node.g + 1 + child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2) + child.f = child.g + child.h + + # Child is already in the open list + for open_node in open_list: + if child == open_node and child.g > open_node.g: + continue + + # Add the child to the open list + open_list.append(child) + + +def main(): + + maze = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] + + start = (0, 0) + end = (7, 6) + + path = astar(maze, start, end) + print(path) + + +if __name__ == '__main__': +main() \ No newline at end of file diff --git a/Graphs/Bellman-ford/c/bellman.c b/Graphs/Bellman-ford/c/bellman.c new file mode 100644 index 000000000..3fb4c365e --- /dev/null +++ b/Graphs/Bellman-ford/c/bellman.c @@ -0,0 +1,78 @@ +//Take a look at the below mentioned lik to know about the algorithm +//https://www.geeksforgeeks.org/bellman-ford-algorithm-dp-23/ + +#include +#define MAX 999999 +#define MIN -999999 + +struct node +{ + int u,v,w; +}a[1000]; + +int d[1000],pi[1000]; + +void main() +{ + int k,i,j,e,n,u,v,w,src; + printf("Enter no. of nodes & edges\n"); + scanf("%d %d",&n,&e); + for(i=0;i%d\n",k,d[k]); + }*/ + } + + + int c=1; + + for(i=0;i%d\n",i,d[i]); + } + } +} \ No newline at end of file diff --git a/Graphs/Bellman-ford/python/bellman.py b/Graphs/Bellman-ford/python/bellman.py new file mode 100644 index 000000000..4a92ce479 --- /dev/null +++ b/Graphs/Bellman-ford/python/bellman.py @@ -0,0 +1,101 @@ +class OrientedGraph: + def __init__(self): + self.nodes = {} + + def insertNode(self, u): + if u not in self.nodes: + self.nodes[u] = {} + + def V(self): + return self.nodes.keys() + + def adj(self, u): + if u in self.nodes: + return self.nodes[u] + + def insertEdge(self, u, v, w=0): + if u not in self.nodes: + self.insertNode(u) + if v not in self.nodes: + self.insertNode(v) + self.nodes[u][v] = w + + def bfs(self, start): + S = [start] + visited = {} + for node in self.V(): + visited[node] = False + visited[start] = True + while len(S) > 0: + u = S.pop(0) + for v in self.adj(u): + print u, v, self.nodes[u][v] + if not visited[v]: + visited[v] = True + S.append(v) + + def dfs(self, start): + S = [start] + visited = {} + for node in self.V(): + visited[node] = False + visited[start] = True + while len(S) > 0: + u = S.pop(-1) + for v in self.adj(u): + print u, v + if not visited[v]: + visited[v] = True + S.append(v) + + def __str__(self): + string = "" + for u in self.V(): + string += (str(u) + "->" + str(self.adj(u)) + "\n") + return string + + def init_bellman(self, source): + d = {} # Stands for destination + p = {} # Stands for predecessor + for node in self.nodes: + d[node] = float('Inf') # We start admiting that the rest of nodes are very very far + p[node] = None + d[source] = 0 # For the source we know how to reach + return d, p + + def relax(self, node, neighbour, graph, d, p): + if d[neighbour] > d[node] + graph[node][neighbour]: + # Record this lower distance + d[neighbour] = d[node] + graph[node][neighbour] + p[neighbour] = node + + def bellman_ford(self, start): + graph = self.nodes + d, p = self.init_bellman(start) + for i in range(len(graph) - 1): #Run this until is converges + for u in graph: + for v in graph[u]: + self.relax(u, v, graph, d, p) # Lets relax it + + for u in graph: + for v in graph[u]: + assert d[v] <= d[u] + graph[u][v] + + print "Costs to reach destination from", start, "after bellman-ford: ", d + return d, p + + +def init(): + graph = OrientedGraph() + for u in ['a', 'b', 'c', 'd', 'e', 'f']: + graph.insertNode(u) + for u, v, w in [('a', 'b', 3), ('a', 'd', 2), ('b', 'c', 0), ('d', 'a', 1), ('d', 'c', 6), ('d', 'e', 10), ('e', 'c', 1), ('e', 'f', 0)]: + graph.insertEdge(u, v, w) + print str(graph) + # Test bellman starting from a + graph.bellman_ford('a') + return + + +if __name__ == "__main__": + init() diff --git a/Graphs/BinaryTree/Binary Tree.cpp b/Graphs/BinaryTree/Binary Tree.cpp new file mode 100644 index 000000000..fc9c1d55a --- /dev/null +++ b/Graphs/BinaryTree/Binary Tree.cpp @@ -0,0 +1,94 @@ +#include +using namespace std; + +struct node +{ + int data; + node* left; + node* right; + +}; + +node* new_node(int data) +{ + node* temp=new node; + temp->data=data; + temp->left=NULL; + temp->right=NULL; + return temp; +} + +node* insert_node(node *root,int data) +{ + if(root==NULL) + return new_node(data); + + else + { + if(root->dataright= insert_node(root->right,data); + + else if(root->data >=data) + root->left= insert_node(root->left,data); + + return root; + + } +} + +node *leftshift(node *root) +{ + return root->left; +} + +node *rightshift(node *root) +{ + return root->right; +} + +void preOrder(node* root) +{ + if(root==NULL) + return ; + else + { + cout<data<<" "; + preOrder(root->left); + preOrder(root->right); + } +} + +int main() +{ + int t; + cin>>t; + int rootData; + cin>>rootData; + + node *root=new_node(rootData); + node *r=new_node(rootData); + t--; + + + while(t--) + { + root=r; + string s; + cin>>s; + for(int i=0;i>data; + + insert_node(root,data); + } + + preOrder(r); + return 0; +} diff --git a/Graphs/BinaryTree/c/binary.c b/Graphs/BinaryTree/c/binary.c new file mode 100644 index 000000000..c315a6339 --- /dev/null +++ b/Graphs/BinaryTree/c/binary.c @@ -0,0 +1,61 @@ +struct node +{ + int data; + struct node *left; + struct node *right; +}; + +/* newNode() allocates a new node with the given data and NULL left and +right pointers. */ +struct node* newNode(int data) +{ +// Allocate memory for new node +struct node* node = (struct node*)malloc(sizeof(struct node)); + +// Assign data to this node +node->data = data; + +// Initialize left and right children as NULL +node->left = NULL; +node->right = NULL; +return(node); +} + + +int main() +{ +/*create root*/ +struct node *root = newNode(1); +/* following is the tree after above statement + + 1 + / \ + NULL NULL +*/ + + +root->left = newNode(2); +root->right = newNode(3); +/* 2 and 3 become left and right children of 1 + 1 + / \ + 2 3 + / \ / \ + NULL NULL NULL NULL +*/ + + +root->left->left = newNode(4); +/* 4 becomes left child of 2 + 1 + / \ + 2 3 + / \ / \ +4 NULL NULL NULL +/ \ +NULL NULL +*/ + +getchar(); +return 0; +} diff --git a/Graphs/BinaryTree/java/binaryTree.java b/Graphs/BinaryTree/java/binaryTree.java new file mode 100644 index 000000000..04fa8396f --- /dev/null +++ b/Graphs/BinaryTree/java/binaryTree.java @@ -0,0 +1,82 @@ +class BinarySearchTree { + + /* Class containing left and right child of current node and key value*/ + class Node { + int key; + Node left, right; + + public Node(int item) { + key = item; + left = right = null; + } + } + + // Root of BST + Node root; + + // Constructor + BinarySearchTree() { + root = null; + } + + // This method mainly calls insertRec() + void insert(int key) { + root = insertRec(root, key); + } + + /* A recursive function to insert a new key in BST */ + Node insertRec(Node root, int key) { + + /* If the tree is empty, return a new node */ + if (root == null) { + root = new Node(key); + return root; + } + + /* Otherwise, recur down the tree */ + if (key < root.key) + root.left = insertRec(root.left, key); + else if (key > root.key) + root.right = insertRec(root.right, key); + + /* return the (unchanged) node pointer */ + return root; + } + + // This method mainly calls InorderRec() + void inorder() { + inorderRec(root); + } + + // A utility function to do inorder traversal of BST + void inorderRec(Node root) { + if (root != null) { + inorderRec(root.left); + System.out.println(root.key); + inorderRec(root.right); + } + } + + // Driver Program to test above functions + public static void main(String[] args) { + BinarySearchTree tree = new BinarySearchTree(); + + /* Let us create following BST + 50 + / \ + 30 70 + / \ / \ + 20 40 60 80 */ + tree.insert(50); + tree.insert(30); + tree.insert(20); + tree.insert(40); + tree.insert(70); + tree.insert(60); + tree.insert(80); + + // print inorder traversal of the BST + tree.inorder(); + } +} +// This code is contributed by Ankur Narain Verma \ No newline at end of file diff --git a/Graphs/BinaryTree/kotlin/binaryKotlin.kt b/Graphs/BinaryTree/kotlin/binaryKotlin.kt new file mode 100644 index 000000000..7cf1e44eb --- /dev/null +++ b/Graphs/BinaryTree/kotlin/binaryKotlin.kt @@ -0,0 +1,35 @@ +// Only Applies To Sorted Data - Efficient Binary Search in Kotlin by Kendall Jackson +internal class BinarySearch { + // Returns index of x if it is present in arr, otherwise -1 + fun binarySearch(arr:IntArray, l:Int, r:Int, target:Int):Int { + if (r >= l) + { + val mid = l + (r-l) / 2 + // If the element is present at the median (edge case gets priority) + if (arr[mid] == target) + return mid + // If target value smaller than median of a sorted array, then + // it can only be in left half of the array + if (arr[mid] > target) + return binarySearch(arr, l, mid - 1, target) + // Can only be present on right half + return binarySearch(arr, mid + 1, r, target) + } + // Not found in array, must return -1 + return -1 + } +} + fun main(args : Array) { + val obj = BinarySearch() + // Test Data + val arr = intArrayOf(2, 3, 4, 9, 40, 97, 945) + + // Searching for value: 9 + val test_value = 9 + val result = obj.binarySearch(arr, 0, arr.size-1, test_value) + // Edge case gets priority again + if (result == -1) + println("Element not found.") + else + println(("Element found at index: " + result)) + } diff --git a/Graphs/BinaryTree/python/binaryTree.py b/Graphs/BinaryTree/python/binaryTree.py new file mode 100644 index 000000000..36b06f5a7 --- /dev/null +++ b/Graphs/BinaryTree/python/binaryTree.py @@ -0,0 +1,64 @@ +#Class which represents a node of binary tree +class Node: + def __init__(self,key): + self.left = None + self.right = None + self.val = key + +#Function which add a key to binary tree +def insert(root,node): + if root is None: + root = node + else: + if root.val < node.val: + if root.right is None: + root.right = node + else: + insert(root.right, node) + else: + if root.left is None: + root.left = node + else: + insert(root.left, node) +#Function to do inorder tree traversal +def inorder(root): + if root: + inorder(root.left) + print(root.val) + inorder(root.right) + +#Function for searching a key in the tree +def search(root,key): + + # Base Cases: root is null or key is present at root + if root is None: + return False + elif root.val == key: + return True + + # Key is greater than root's key + if root.val < key: + return search(root.right,key) + + # Key is smaller than root's key + return search(root.left,key) + + +#Test case + +r = Node(50) +insert(r,Node(30)) +insert(r,Node(20)) +insert(r,Node(40)) +insert(r,Node(70)) +insert(r,Node(60)) +insert(r,Node(80)) + +print "Result of traversing" +inorder(r) + + +print "Is 25 in the tree?", search(r,25) +print "Is 30 in the tree?", search(r,30) +print "Is 2 in the tree?", search(r,2) + diff --git a/Graphs/BinaryTree/python/binaryTreeFromInfixNPrefix.py b/Graphs/BinaryTree/python/binaryTreeFromInfixNPrefix.py new file mode 100644 index 000000000..ab0593433 --- /dev/null +++ b/Graphs/BinaryTree/python/binaryTreeFromInfixNPrefix.py @@ -0,0 +1,40 @@ +############################################## +height = 0 +strings = [] +def makeTree(inT,posT,level): + global height + tree = Node(posT[0],level) + indRoot = inT.index(tree.root) + lenL = indRoot + lenR = len(inT)-1-indRoot + if(height<(level+1)): + height = level+1 + if(len(inT)==1 and len(posT)==1): + return tree + else: + try: + tree.left = makeTree(inT[:indRoot],posT[1:(lenL+1)],level+1) + except IndexError: + tree.left = None + try: + tree.right = makeTree(inT[(indRoot+1):],posT[(lenL+1):],level+1) + except: + tree.right = None + return tree +############################################## +class Node: + def __init__(self,key,level): + self.left = None + self.right = None + self.root = key + self.level = level +############################################## +infx = "bac" +prefx = "abc" +tree = makeTree(infx,prefx,0) #tree object is created such as below + +''' + a + / \ + b c +''' diff --git a/Graphs/Diameter_of_tree/Diameter_of_tree.cpp b/Graphs/Diameter_of_tree/Diameter_of_tree.cpp new file mode 100644 index 000000000..26656db08 --- /dev/null +++ b/Graphs/Diameter_of_tree/Diameter_of_tree.cpp @@ -0,0 +1,85 @@ +#include +using namespace std; + +#define INF 0x3f3f3f3f +#define MOD 1000000007 + +#define ll long long +#define pb push_back +#define nl printf("\n"); +#define vint vector + +vector>g[100005]; +int n; +int dist[100005]; +void shortest_path(int s) +{ + for(int i=0;i<100001;i++) + dist[i]=INF; + set> setds; + + setds.insert({0,s}); + dist[s]=0; + while(!setds.empty()) + { + pair temp; + temp=*(setds.begin()); + setds.erase(setds.begin()); + + int u=temp.second; + vector>::iterator it; + for(it=g[u].begin();it!=g[u].end();it++) + { + int v = (*it).first; + int weight = (*it).second; + if(dist[v] > dist[u] + weight) + { + if(dist[v] != INF) + setds.erase(setds.find({dist[v],v})); + + dist[v]=dist[u] + weight; + setds.insert({dist[v],v}); + } + } + } + + // printf("Vertex Distance from Source\n"); + // for (int i = 0; i <= n ; ++i) + // printf("%d \t\t %d\n", i, dist[i]); + +} + +int main() +{ + ifstream myFile("task.in"); + if(!myFile.fail()) + { + assert(freopen("task.in", "r", stdin)); + } + int m; + cin>>n>>m; + n--; //starting from 0 + int total=0; + for(int i=0;i>x>>y>>w; + g[x].pb({y,w}); + g[y].pb({x,w}); + total+=w; + } + shortest_path(0); + int ma=0,ind; + for(int i=0;i ma) + ind=i,ma=dist[i]; + for(int i=0;100001;i++) + dist[i]=INF; + shortest_path(ind); + for(int i=0;i ma) + ind=i,ma=dist[i]; + cout<<(total - dist[ind]); + nl + return 0; +} diff --git a/Graphs/Dijkstra Algorithm/C#/Dijkstra.cs b/Graphs/Dijkstra Algorithm/C#/Dijkstra.cs new file mode 100644 index 000000000..05da1079c --- /dev/null +++ b/Graphs/Dijkstra Algorithm/C#/Dijkstra.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics; +namespace DijkstraAlgorithm +{ + class Dijkstra + { + private static int MinimumDistance(int[] distance, bool[] shortestPathTreeSet, int verticesCount) + { + int min = int.MaxValue; + int minIndex = 0; + for (int v = 0; v < verticesCount; ++v) + { + if (shortestPathTreeSet[v] == false && distance[v] <= min) + { + min = distance[v]; + minIndex = v; + } + } + return minIndex; + } + private static void Print(int[] distance, int verticesCount) + { + Console.WriteLine("Vertex Distance from source"); + for (int i = 0; i < verticesCount; ++i) + Console.WriteLine("{0}\t {1}", i, distance[i]); + } + public static void DijkstraAlgo(int[,] graph, int source, int verticesCount) + { + int[] distance = new int[verticesCount]; + bool[] shortestPathTreeSet = new bool[verticesCount]; + for (int i = 0; i < verticesCount; ++i) + { + distance[i] = int.MaxValue; + shortestPathTreeSet[i] = false; + } + distance[source] = 0; + for (int count = 0; count < verticesCount - 1; ++count) + { + int u = MinimumDistance(distance, shortestPathTreeSet, verticesCount); + shortestPathTreeSet[u] = true; + for (int v = 0; v < verticesCount; ++v) + if (!shortestPathTreeSet[v] && Convert.ToBoolean(graph[u, v]) && distance[u] != int.MaxValue && distance[u] + graph[u, v] < distance[v]) + distance[v] = distance[u] + graph[u, v]; + } + Print(distance, verticesCount); + } + static void Main(string[] args) + { + int[,] graph = { + { 0, 6, 0, 0, 0, 0, 0, 9, 0 }, + { 6, 0, 9, 0, 0, 0, 0, 11, 0 }, + { 0, 9, 0, 5, 0, 6, 0, 0, 2 }, + { 0, 0, 5, 0, 9, 16, 0, 0, 0 }, + { 0, 0, 0, 9, 0, 10, 0, 0, 0 }, + { 0, 0, 6, 0, 10, 0, 2, 0, 0 }, + { 0, 0, 0, 16, 0, 2, 0, 1, 6 }, + { 9, 11, 0, 0, 0, 0, 1, 0, 5 }, + { 0, 0, 2, 0, 0, 0, 6, 5, 0 } + }; + DijkstraAlgo(graph, 0, 9); + } + } +} \ No newline at end of file diff --git a/graph/dijkstra/Java/Grafo.java b/Graphs/Dijkstra Algorithm/Java/Grafo.java similarity index 58% rename from graph/dijkstra/Java/Grafo.java rename to Graphs/Dijkstra Algorithm/Java/Grafo.java index 0f1530b3b..5dcd10ca4 100644 --- a/graph/dijkstra/Java/Grafo.java +++ b/Graphs/Dijkstra Algorithm/Java/Grafo.java @@ -22,18 +22,18 @@ public Grafo(){ /** - * Mtodo que verifica se um vertice - * @param v Nome do vrtice - * @return Uma resposta true caso o nome seja de um vrtice, e false caso no + * Método que verifica se é um vertice + * @param v Nome do vértice + * @return Uma resposta true caso o nome seja de um vértice, e false caso não */ public boolean isVertex(String v) { return graph.containsKey(v); } /** - * Mtodo que adiciona um vertice se ele nao existir - * @param v Nome do vrtice - * @return O nome do vrtice + * Método que adiciona um vertice se ele nao existir + * @param v Nome do vértice + * @return O nome do vértice */ public String addVertex(String v) { if(!isVertex(v)){ @@ -44,8 +44,8 @@ public String addVertex(String v) { } /** - * Mtodo que emove um vertice e suas arestas se ele existir - * @param v Nome do vtice + * Método que emove um vertice e suas arestas se ele existir + * @param v Nome do vétice */ public void removeVertex(String v) { if(isVertex(v)) { @@ -56,36 +56,36 @@ public void removeVertex(String v) { } /** - * Mtodo que retorna o numero de vertices - * @return O tamanho do grafo (nmero de vrtices) + * Método que retorna o numero de vertices + * @return O tamanho do grafo (número de vértices) */ public int numVertex() { return graph.size(); } /** - * Mtodo que retorna o iterator dos vertices - * @return O itertador com todos os nomes das estaes (vtices) do grafo + * Método que retorna o iterator dos vertices + * @return O itertador com todos os nomes das estações (vétices) do grafo */ public Iterable getVertex() { return graph.keySet(); } /** - * Mtodo que verifica se uma aresta - * @param v Nome do vrtice de incio (estao de partida) - * @param u Nome do vrtice final (estao de destino) - * @return Uma resposta true casoseja uma aresta, e false, caso no + * Método que verifica se é uma aresta + * @param v Nome do vértice de início (estação de partida) + * @param u Nome do vértice final (estação de destino) + * @return Uma resposta true casoseja uma aresta, e false, caso não */ public boolean isEdge(String v, String u) { return graph.containsKey(v) && graph.get(v).containsKey(u); } /** - * Mtodo que adiciona uma aresta se ela nao existir - * @param v Nome do vrtice de incio (estao de partida) - * @param u Nome do vrtice final (estao de destino) - * @param t Tempo que leva de uma estao at outra + * Método que adiciona uma aresta se ela nao existir + * @param v Nome do vértice de início (estação de partida) + * @param u Nome do vértice final (estação de destino) + * @param t Tempo que leva de uma estação até outra */ public void addEdge(String v, String u, Double t) { if(!isEdge(v, u) && t > 0) { @@ -95,9 +95,9 @@ public void addEdge(String v, String u, Double t) { } /** - * Mtodo que retorna uma aresta se ela existir - * @param v Nome do vrtice de incio (estao de partida) - * @param u Nome do vrtice final (estao de destino) + * Método que retorna uma aresta se ela existir + * @param v Nome do vértice de início (estação de partida) + * @param u Nome do vértice final (estação de destino) * @return */ public double getEdge(String v, String u) { @@ -105,9 +105,9 @@ public double getEdge(String v, String u) { } /** - * Mtodo que remove uma aresta se ela existir - * @param u Nome do vrtice de incio (estao de partida) - * @param v Nome do vrtice final (estao de destino) + * Método que remove uma aresta se ela existir + * @param u Nome do vértice de início (estação de partida) + * @param v Nome do vértice final (estação de destino) */ public void removeEdge(String u, String v) { if(isEdge(v, u)) { @@ -117,28 +117,28 @@ public void removeEdge(String u, String v) { } /** - * Mtodo que retorna o numero de arestas ajacentes do vertice, ou -1 se nao existir - * @param v Nome da estao (vrtice) - * @return O nmero de arestas que esto ligadas ao vtices, ou -1 caso no tenha + * Método que retorna o numero de arestas ajacentes do vertice, ou -1 se nao existir + * @param v Nome da estação (vértice) + * @return O número de arestas que estão ligadas ao vétices, ou -1 caso não tenha */ public int numEdge(String v) { return isVertex(v) ? graph.get(v).size() : -1; } /** - * Mtodo que retorna o iterator dos vertices adjacentes, ou null se sao exitir - * @param v Nome do vtice - * @return O iterador com todos os vtices adjacentes do vrtice atual + * Método que retorna o iterator dos vertices adjacentes, ou null se sao exitir + * @param v Nome do vétice + * @return O iterador com todos os vétices adjacentes do vértice atual */ public Iterable getAdjacent(String v) { return isVertex(v) ? graph.get(v).keySet() : null; } /** - * Algoritmo de Dijikstra: Define os caminhos de um vrtice at o outro, inclusive o mnimo - * @param v Nome do vrtice de incio (estao de partida) - * @param u Nome do vrtice final (estao de destino) - * @return Uma HashMap com os caminho mnimo + * Algoritmo de Dijikstra: Define os caminhos de um vértice até o outro, inclusive o mínimo + * @param v Nome do vértice de início (estação de partida) + * @param u Nome do vértice final (estação de destino) + * @return Uma HashMap com os caminho mínimo */ public Stack dijkstra(String v, String u) { //Verifica se os vertice existem @@ -180,11 +180,11 @@ public Stack dijkstra(String v, String u) { } /** - * Mtodo que converte os vtices visitados em uma pilha de paths (caminhos) - * @param visited HashMap com os vtices visitados no algoritmo de caminho mnimo - * @param v Nome do vrtice de incio (estao de partida) - * @param u Nome do vrtice final (estao de destino) - * @return Uma estrutura de pilha com os vtices visitados + * Método que converte os vétices visitados em uma pilha de paths (caminhos) + * @param visited HashMap com os vétices visitados no algoritmo de caminho mínimo + * @param v Nome do vértice de início (estação de partida) + * @param u Nome do vértice final (estação de destino) + * @return Uma estrutura de pilha com os vétices visitados */ private Stack getPath(HashMap visited, String v, String u) { Stack path = new Stack<>(); @@ -198,4 +198,4 @@ private Stack getPath(HashMap visited, String v, String u) { return path; } -} \ No newline at end of file +} diff --git a/graph/dijkstra/Java/Path.java b/Graphs/Dijkstra Algorithm/Java/Path.java similarity index 70% rename from graph/dijkstra/Java/Path.java rename to Graphs/Dijkstra Algorithm/Java/Path.java index 4baca9c93..c84505fa0 100644 --- a/graph/dijkstra/Java/Path.java +++ b/Graphs/Dijkstra Algorithm/Java/Path.java @@ -1,7 +1,7 @@ package util; /** - * Classe que representa um caminho entre dois vrtices + * Classe que representa um caminho entre dois vértices * @author Brendo Nascimento e Gabriel Azevedo * */ @@ -12,10 +12,10 @@ public class Path implements Comparable{ private Double time; /** - * Mtodo construtor - * @param v Vrtice inicial (estao de partida) - * @param p Vrtice final (estao de chegada) - * @param t Tempo que leva para ir da estao de partida at a chegada + * Método construtor + * @param v Vértice inicial (estação de partida) + * @param p Vértice final (estação de chegada) + * @param t Tempo que leva para ir da estação de partida até a chegada */ public Path(String v, String p, double t) { vertex = v; @@ -49,10 +49,10 @@ public void setTime(double t) { } /** - * Mtodo que compara o tempo entre caminhos + * Método que compara o tempo entre caminhos */ public int compareTo(Path p) { return time.compareTo(p.getTime()); } -} \ No newline at end of file +} diff --git a/graph/dijkstra/cpp/dijkstra.cpp b/Graphs/Dijkstra Algorithm/cpp/dijkstra.cpp similarity index 100% rename from graph/dijkstra/cpp/dijkstra.cpp rename to Graphs/Dijkstra Algorithm/cpp/dijkstra.cpp diff --git a/graph/dijkstra/javascript/dijikstras.js b/Graphs/Dijkstra Algorithm/javascript/dijikstras.js similarity index 100% rename from graph/dijkstra/javascript/dijikstras.js rename to Graphs/Dijkstra Algorithm/javascript/dijikstras.js diff --git a/Graphs/Dijkstra Algorithm/python/Dijkastra's_algo.py b/Graphs/Dijkstra Algorithm/python/Dijkastra's_algo.py new file mode 100644 index 000000000..ff4c613d9 --- /dev/null +++ b/Graphs/Dijkstra Algorithm/python/Dijkastra's_algo.py @@ -0,0 +1,46 @@ +from collections import defaultdict +from heapq import * + +def dijkstra(edges, f, t): + g = defaultdict(list) + for l,r,c in edges: + g[l].append((c,r)) + + q, seen, mins = [(0,f,())], set(), {f: 0} + while q: + (cost,v1,path) = heappop(q) + if v1 not in seen: + seen.add(v1) + path = (v1, path) + if v1 == t: return (cost, path) + + for c, v2 in g.get(v1, ()): + if v2 in seen: continue + prev = mins.get(v2, None) + next = cost + c + if prev is None or next < prev: + mins[v2] = next + heappush(q, (next, v2, path)) + + return float("inf") + +if __name__ == "__main__": + edges = [ + ("A", "B", 7), + ("A", "D", 5), + ("B", "C", 8), + ("B", "D", 9), + ("B", "E", 7), + ("C", "E", 5), + ("D", "E", 15), + ("D", "F", 6), + ("E", "F", 8), + ("E", "G", 9), + ("F", "G", 11) + ] + print("=== Dijkstra ===") + print(edges) + print("A -> E:") + print(dijkstra(edges, "A", "E")) + print("F -> G:") + print(dijkstra(edges, "F", "G")) diff --git a/graph/dijkstra/python/dijkstra.py b/Graphs/Dijkstra Algorithm/python/dijkstra.py similarity index 99% rename from graph/dijkstra/python/dijkstra.py rename to Graphs/Dijkstra Algorithm/python/dijkstra.py index 7ea9730b3..2d4596090 100644 --- a/graph/dijkstra/python/dijkstra.py +++ b/Graphs/Dijkstra Algorithm/python/dijkstra.py @@ -48,4 +48,4 @@ def dijkstra(self, src): [0, 0, 2, 0, 0, 0, 6, 7, 0] ]; -g.dijkstra(0); \ No newline at end of file +g.dijkstra(0); diff --git a/graph/dijkstra/ruby/dijkstra.rb b/Graphs/Dijkstra Algorithm/ruby/dijkstra.rb similarity index 99% rename from graph/dijkstra/ruby/dijkstra.rb rename to Graphs/Dijkstra Algorithm/ruby/dijkstra.rb index 9ae3b2c4c..19eb61792 100644 --- a/graph/dijkstra/ruby/dijkstra.rb +++ b/Graphs/Dijkstra Algorithm/ruby/dijkstra.rb @@ -81,4 +81,4 @@ def validate(adjacences) end adjacences end -end \ No newline at end of file +end diff --git a/graph/dijkstra/ruby/dijkstra_test.rb b/Graphs/Dijkstra Algorithm/ruby/dijkstra_test.rb similarity index 99% rename from graph/dijkstra/ruby/dijkstra_test.rb rename to Graphs/Dijkstra Algorithm/ruby/dijkstra_test.rb index c9f29a23b..78e4c0dbb 100644 --- a/graph/dijkstra/ruby/dijkstra_test.rb +++ b/Graphs/Dijkstra Algorithm/ruby/dijkstra_test.rb @@ -43,4 +43,4 @@ def test_find_shortest_paths assert_equal expected, actual end -end \ No newline at end of file +end diff --git a/graph/Finding Articulation Points and bridges/cpp/Finding Articulation Points and bridges.cpp b/Graphs/Finding Articulation Points and bridges/cpp/Finding Articulation Points and bridges.cpp similarity index 100% rename from graph/Finding Articulation Points and bridges/cpp/Finding Articulation Points and bridges.cpp rename to Graphs/Finding Articulation Points and bridges/cpp/Finding Articulation Points and bridges.cpp diff --git a/Graphs/Floyd/Cplusplus/floydWarshall.cpp b/Graphs/Floyd/Cplusplus/floydWarshall.cpp new file mode 100644 index 000000000..4eb383599 --- /dev/null +++ b/Graphs/Floyd/Cplusplus/floydWarshall.cpp @@ -0,0 +1,89 @@ +#include +#include +using namespace std; +#define dir true +#define n_dir false +class grafo{ + private: + struct head_graph{ + int **matriz_ad; + int numvert; + int numares; + bool direct; + }; + bool criado = false; + head_graph g; + public: + void create_graph(int tmax, bool tipo){ + g.matriz_ad = new int*[tmax]; + for(int i = 0; i < tmax; i++){ + g.matriz_ad[i] = new int[tmax]; + } + g.numares = 0; + g.numvert = tmax; + g.direct = tipo; + criado = true; + for(int i = 0; i g.matriz_ad[i][k] +g.matriz_ad[k][j])){ + g.matriz_ad[i][j] = g.matriz_ad[i][k] +g.matriz_ad[k][j]; + } + } + } + } + } + + void add_edge(int u, int v, int peso){ + if(criado){ + g.numares++; + g.matriz_ad[u][v] = peso; + if(!g.direct){ + g.matriz_ad[v][u] = peso; + } + } + } + + void matriz_ad(){ + for(int i = 0; i < g.numvert; i++){ + for(int j = 0; j< g.numvert; j++){ + if(g.matriz_ad[i][j] == INT_MAX){ + printf("I "); + }else{ + printf("%d ", g.matriz_ad[i][j]); + } + } + printf("\n"); + } + } +}; +int main(){ + grafo g; + g.create_graph(4,dir); + g.add_edge(1,0,2); + g.add_edge(0,2,3); + g.add_edge(2,3,1); + g.add_edge(3,0,6); + g.add_edge(2,1,7); + printf("initial matriz of adjacency(I is infinity)\n"); + g.matriz_ad(); + g.floyd_warshall(); + printf("end matriz of adjacency\n"); + g.matriz_ad(); + return 0; +} diff --git a/Graphs/Floyd/Java/Floyds.java b/Graphs/Floyd/Java/Floyds.java new file mode 100644 index 000000000..45571ba3c --- /dev/null +++ b/Graphs/Floyd/Java/Floyds.java @@ -0,0 +1,32 @@ +import java.util.Scanner; + +public class Floyds { + public static int min(int a,int b){ + return a>b?b:a; + } + + public static void main(String args[]){ + Scanner in = new Scanner(System.in); + System.out.print("\nEnter the number of nodes: "); + int n = in.nextInt(); + int [][]mat = new int[n][n]; + System.out.println("Enter the matrix"); + for(int i=0;i queue = new LinkedList(); + queue.add(s); + visited[s] = true; + parent[s]=-1; + + // Standard BFS Loop + while (queue.size()!=0) + { + int u = queue.poll(); + + for (int v=0; v 0) + { + queue.add(v); + parent[v] = u; + visited[v] = true; + } + } + } + + // If we reached sink in BFS starting from source, then + // return true, else false + return (visited[t] == true); + } + + // Returns tne maximum flow from s to t in the given graph + int fordFulkerson(int graph[][], int s, int t) + { + int u, v; + + // Create a residual graph and fill the residual graph + // with given capacities in the original graph as + // residual capacities in residual graph + + // Residual graph where rGraph[i][j] indicates + // residual capacity of edge from i to j (if there + // is an edge. If rGraph[i][j] is 0, then there is + // not) + int rGraph[][] = new int[V][V]; + + for (u = 0; u < V; u++) + for (v = 0; v < V; v++) + rGraph[u][v] = graph[u][v]; + + // This array is filled by BFS and to store path + int parent[] = new int[V]; + + int max_flow = 0; // There is no flow initially + + // Augment the flow while tere is path from source + // to sink + while (bfs(rGraph, s, t, parent)) + { + // Find minimum residual capacity of the edhes + // along the path filled by BFS. Or we can say + // find the maximum flow through the path found. + int path_flow = Integer.MAX_VALUE; + for (v=t; v!=s; v=parent[v]) + { + u = parent[v]; + path_flow = Math.min(path_flow, rGraph[u][v]); + } + + // update residual capacities of the edges and + // reverse edges along the path + for (v=t; v != s; v=parent[v]) + { + u = parent[v]; + rGraph[u][v] -= path_flow; + rGraph[v][u] += path_flow; + } + + // Add path flow to overall flow + max_flow += path_flow; + } + + // Return the overall flow + return max_flow; + } + + // Driver program to test above functions + public static void main (String[] args) throws java.lang.Exception + { + // Let us create a graph shown in the above example + int graph[][] =new int[][] { {0, 16, 13, 0, 0, 0}, + {0, 0, 10, 12, 0, 0}, + {0, 4, 0, 0, 14, 0}, + {0, 0, 9, 0, 0, 20}, + {0, 0, 0, 7, 0, 4}, + {0, 0, 0, 0, 0, 0} + }; + MaxFlow m = new MaxFlow(); + + System.out.println("The maximum possible flow is " + + m.fordFulkerson(graph, 0, 5)); + + } +} diff --git a/Graphs/HLD/hld.txt b/Graphs/HLD/hld.txt new file mode 100644 index 000000000..aaaa2ab20 --- /dev/null +++ b/Graphs/HLD/hld.txt @@ -0,0 +1,133 @@ +// chain formation + +#inclue +using namespace std; +#define sz 100005 +vectorgr[sz]; + +int no=0; //count number of chains existing +int head[sz]; // head of each chain +int ind[sz]; // chain no. of a node +int pos[sz]; // position of a node in its chain +int csize[sz]; //size of a particular chain +int sub[sz],par[sz]; +void dfs(int src,int parent){ + sub[src]=1; + par[src]=parent; + for(int i=0;i<(int)gr[src].size();++i){ + int ver=gr[src][i]; + if(ver==parent) continue; + dfs(ver,src); + } + sub[parent]+=sub[src]; +} + +void hld(int src){ + if(head[no]==-1) head[no]=src; + ind[src]=no; + pos[src]=csize[no]; + csize[no]++; + + int ind=-1,mx=0; // if ind=0 then index problem in subtree + + for(int i=0;i<(int)gr[src].size();++i){ + int ver=gr[src][i]; + if(ver==par[src]) continue; + if(sub[ver]>=mx){ + mx=sub[ver]; + ind=i; + } + } + + if(ind>=0) hld(gr[src][ind]); //special child i.e subtree is mazmum + + for(int i=0;i<(int)gr[src].size();++i){ //other will be other chain + int ver=gr[src][i]; + if(ver==par[src] or i==ind) continue; + ++no; + hld(ver); + } + + +} + + + + +int LCA(int u,int v){ + + if(lv[u]>lv[v]) swap(u,v); + int diff=abs(lv[u]-lv[v]); + + for(int i=13;i>=0;--i) + if((1<=0;--i){ + if(par[v][i]!=par[u][i]){ + v=par[v][i]; + u=par[u][i]; + } + } + return par[u][0]; + +} + + +//LCA IN HLD + + + +int up_qry(int u,int v){ + + if(u==v) return 0; + int uchain=ind[u],vchain=ind[v]; + int ans=-1; + while(1){ + uchain=ind[u]; + if(uchain==vchain){ + if(u==v) break; + segqry(1,1,ptr-1,inpos[v],inpos[u]); // according to need + if(qt[1]>ans) ans=qt[1]; + break; + } + segqry(1,1,ptr-1,inpos[head[uchain]],inpos[u]); // chkpt + if(qt[1]>ans) ans=qt[1]; + + u=head[uchain]; + u=par[u][0]; + + } + return ans; + +} + + +void qry(int u,int v){ + int lca=LCA(u,v); + return max(up_qry(u,lca),up_qry(v,lca)); +} + + +void upd(int node,int s,int e,int ind,int val){ + + if(s==e){ + seg[node]=val; + return; + } + int mid=(s+e)>>1; + if(ind<=mid) upd(2*node,s,mid,ind,val); + else upd(2*node+1,mid+1,e,ind,val); + + seg[node]=max(seg[2*node],seg[2*node+1]); + +} + +void segqry(int node,int s,int e,int l,int r){ + + if(r>1; + return max(segqry(2*node,s,mid,l,r),segqry(2*node+1,mid+1,e,l,r)); +} \ No newline at end of file diff --git a/Graphs/Kosaraju ALgorithm/Kosaraju_ALgorithm.cpp b/Graphs/Kosaraju ALgorithm/Kosaraju_ALgorithm.cpp new file mode 100644 index 000000000..116997094 --- /dev/null +++ b/Graphs/Kosaraju ALgorithm/Kosaraju_ALgorithm.cpp @@ -0,0 +1,91 @@ +#include +#include + +#define MAX_DEGREE 5 +#define MAX_NUM_VERTICES 20 + +struct vertices_s { + int visited; + int deg; + int adj[MAX_DEGREE]; /* < 0 if incoming edge */ +} vertices[] = { + {0, 3, {2, -3, 4}}, + {0, 2, {-1, 3}}, + {0, 3, {1, -2, 7}}, + {0, 3, {-1, -5, 6}}, + {0, 2, {4, -7}}, + {0, 3, {-4, 7, -8}}, + {0, 4, {-3, 5, -6, -12}}, + {0, 3, {6, -9, 11}}, + {0, 2, {8, -10}}, + {0, 3, {9, -11, -12}}, + {0, 3, {-8, 10, 12}}, + {0, 3, {7, 10, -11}} +}; +int num_vertices = sizeof(vertices) / sizeof(vertices[0]); + +struct stack_s { + int top; + int items[MAX_NUM_VERTICES]; +} stack = {-1, {}}; + +void stack_push(int v) { + stack.top++; + if (stack.top < MAX_NUM_VERTICES) + stack.items[stack.top] = v; + else { + printf("Stack is full!\n"); + exit(1); + } +} + +int stack_pop() { + return stack.top < 0 ? -1 : stack.items[stack.top--]; +} + +void dfs(int v, int transpose) { + int i, c, n; + vertices[v].visited = 1; + for (i = 0, c = vertices[v].deg; i < c; ++i) { + n = vertices[v].adj[i] * transpose; + if (n > 0) + /* n - 1 because vertex indexing begins at 0 */ + if (!vertices[n - 1].visited) + dfs(n - 1, transpose); + } + if (transpose < 0) + stack_push(v); + else + printf("%d ", v + 1); +} + +void reset_visited() { + int i; + for (i = 0; i < num_vertices; ++i) + vertices[i].visited = 0; +} + +void order_pass() { + int i; + for (i = 0; i < num_vertices; ++i) + if (!vertices[i].visited) + dfs(i, -1); +} + +void scc_pass() { + int i = 0, v; + while((v = stack_pop()) != -1) { + if (!vertices[v].visited) { + printf("scc %d: ", ++i); + dfs(v, 1); + printf("\n"); + } + } +} + +int main(void) { + order_pass(); + reset_visited(); + scc_pass(); + return 0; +} diff --git a/Graphs/LCA/lca.cpp b/Graphs/LCA/lca.cpp new file mode 100644 index 000000000..d893b46f1 --- /dev/null +++ b/Graphs/LCA/lca.cpp @@ -0,0 +1,77 @@ +#include +#include +using namespace std; +int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; +#define mod 1000000007 +#define CLEAR(a) memset((a),0,sizeof(a)) +#define ll long long int +#define pii pair +#define level 18 +vector tree[100000]; +int depth[100000]; +int parent[100000][18]; +void dfs(int cur, int prev) +{ + depth[cur] = depth[prev] + 1; + parent[cur][0] = prev; + for (int i=0; i>i)&1) + v = parent[v][i]; + if (u == v) + return u; + for (int i=level-1; i>=0; i--) + if (parent[u][i] != parent[v][i]) + { + u = parent[u][i]; + v = parent[v][i]; + } + return parent[u][0]; +} +int main() +{ + memset(parent,-1,sizeof(parent)); + int n; + cin>>n; + for(int i=0;i>a>>b; + tree[a].push_back(b); + tree[b].push_back(a); + } + depth[0] = 0; + dfs(1,0); + precomputeSparseMatrix(n); + int q; + cin>>q; + while(q--) + { + int a,b; + cin>>a>>b; + cout< +#include + +using namespace std; + +#define ll long long + +#define rep(i,a,b) for(ll i=a;i adj[N]; +ll n,cnt=0; + +void dfs(ll node,ll par,ll lev){ + euler[cnt]=node; + level[cnt]=lev; + cnt++; + for(auto i:adj[node]){ + if(i!=par){ + dfs(i,node,lev+1); + euler[cnt]=node; + level[cnt]=lev; + cnt++; + } + } +} + +void fillsparse(){ + rep(i,0,2*n-1) dp[i][0]=i; + rep(i,1,logN){ + ll p = 1<r) swap(l,r); + ll d = r - l; + ll k = log2(d); + if(l==r) return euler[l]; + if(level[dp[l][k]]>level[dp[r-(1<>n; + rep(i,0,n-1){ + ll u,v; + cin>>u>>v; + adj[u].pb(v); + adj[v].pb(u); + } + cnt=0;dfs(1,0,1); + rep(i,1,n+1) first[i]=-1;; + rep(i,0,2*n-1) + if(first[euler[i]]==-1) first[euler[i]]=i; + fillsparse(); + ll q; + cin>>q; + rep(i,0,q){ + ll u,v; + cin>>u>>v; + ll lca1 = lca(u,v); + cout<` is a custom, generic implementation of a dynamic array that resizes itself at every addition and deletion. `LinkedList` is a custom, generic, doubly-linked list. These have been taken directly from a university project and could probably be optimised considerably. + +A graph is represented as an `ArrayList` of nodes. Each node is a `LinkedList` of edges connected to it. An edge has an origin node index, a destination node index, and a metric (edge 'weight'/'length'). + +#### Directionality +The DJP algorithm implementation treats the graph representation as undirected, whereas the Kruskal's algorithm implementation treats it as directed. Pretty much the only implication here is that DJP can find multiple connections (edges) between each pair of nodes, and it only considers the cheapest one for its spanning tree. The `LinkedGraph` structure can easily be used for purely undirected graphs as well, because it stores each edge in the lists of both end nodes. diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/ArrayList.cpp b/Graphs/Minimum Spanning Tree/C++/data-structures/ArrayList.cpp new file mode 100644 index 000000000..1a12b4d1a --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/ArrayList.cpp @@ -0,0 +1,127 @@ +#include +#include +#include +#include "LinkedList.hpp" +#include "LinkedGraphEdge.hpp" +#include "ArrayList.hpp" + +template +ArrayList::ArrayList() { + this->size = 0; + this->array = new T[size]; +} + +template +ArrayList::~ArrayList() { + delete[] array; +} + +template +int ArrayList::getSize() { + return this->size; +} + +template +T ArrayList::get(int index) { + if (index < this->size && index >= 0) + return this->array[index]; + else + throw std::out_of_range("Index out of bounds"); +} + +template +bool ArrayList::contains(const T value) { + for (int i = 0; i < this->size; i++) { + if (this->array[i] == value) + return true; + } + return false; +} + +template +void ArrayList::add(const T value, int index) { + if (index <= this->size && index >= 0) { + T *newArray = new T[++this->size]; + for (int i = 0; i < this->size; i++) { + if (i < index) + newArray[i] = this->array[i]; + else { + if (i == index) + newArray[i] = value; + else + newArray[i] = this->array[i - 1]; + } + } + delete[] this->array; + this->array = newArray; + } + else + throw std::out_of_range("Index out of bounds"); +} + +template +void ArrayList::add(const T value) { + T *newArray = new T[++this->size]; + for (int i = 0; i < this->size; i++) + newArray[i] = this->array[i]; + newArray[this->size - 1] = value; + delete [] this->array; + this->array = newArray; +} + +template +void ArrayList::addStart(const T value) { + add(value, 0u); +} + +template +void ArrayList::addEnd(const T value) { + add(value); +} + +template +void ArrayList::removeAt(int index) { + if (index < this->size && index >= 0) { + T *newArray = new T[--this->size]; + for (int i = 0; i < this->size; i++) { + if (i < index) + newArray[i] = this->array[i]; + else + newArray[i] = this->array[i + 1]; + } + delete[] this->array; + this->array = newArray; + } + else + throw std::out_of_range("Index out of bounds"); +} + +template +void ArrayList::removeFirst() { + removeAt(0u); +} + +template +void ArrayList::removeLast() { + removeAt(getSize() - 1); +} + +template +void ArrayList::remove(const T value) { + for (int i = 0; i < this->size; i++) { + if (this->array[i] == value) { + removeAt(i); + return; + } + } +} + +template +void ArrayList::print() { + for (int i = 0; i < this->size; i++) { + std::cout << array[i] << " "; + } + std::cout << "\n"; +} + +template class ArrayList*>; diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/ArrayList.hpp b/Graphs/Minimum Spanning Tree/C++/data-structures/ArrayList.hpp new file mode 100644 index 000000000..e8ab6a1e4 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/ArrayList.hpp @@ -0,0 +1,30 @@ +#ifndef MST_ARRAYLIST_HPP_ +#define MST_ARRAYLIST_HPP_ + +template +class ArrayList { + +private: + T *array; + int size; + +public: + ArrayList(); + ~ArrayList(); + + int getSize(); + T get(int index); + bool contains(T const value); + void add(T const value, int index); + void add(T const value); + void addStart(T const value); + void addEnd(T const value); + void removeAt(int index); + void removeFirst(); + void removeLast(); + void remove(T const value); + void print(); + +}; + +#endif //MST_ARRAYLIST_H diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraph.cpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraph.cpp new file mode 100644 index 000000000..31691dc30 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraph.cpp @@ -0,0 +1,78 @@ +#include +#include +#include "LinkedGraph.hpp" + +LinkedGraph::LinkedGraph(int nodeCount) { + addNodes(nodeCount); +} + +void LinkedGraph::addNodes(int count) { + for (int i = 0; i < count; i++) { + nodes->add(new LinkedList()); + } +} + +void LinkedGraph::addEdge(int origin, int destination, int metric) { + if (origin < nodes->getSize() && destination < nodes->getSize() + && origin >= 0 && destination >= 0 && metric > 0) { + LinkedGraphEdge* edge = new LinkedGraphEdge(origin, destination, metric); + nodes->get(origin)->add(edge); + nodes->get(destination)->add(edge); + } +} + +void LinkedGraph::clear() { + for (int i = 0; i < nodes->getSize(); i++) { + delete nodes->get(i); + } + delete nodes; + nodes = new ArrayList*>(); +} + +std::string LinkedGraph::toString() { + std::stringstream stringStream; + for (int i = 0; i < nodes->getSize(); i++) { + stringStream << std::to_string(i) << " : "; + for (int k = 0; k < nodes->get(i)->getSize(); k++) { + if (k > 0) { + stringStream << ", "; + } + stringStream << "{"; + stringStream << std::to_string(nodes->get(i)->get(k)->originNode); + stringStream << "->"; + stringStream << std::to_string(nodes->get(i)->get(k)->destinationNode); + stringStream << ", "; + stringStream << std::to_string(nodes->get(i)->get(k)->metric); + stringStream << "}"; + } + stringStream << "\n"; + } + stringStream.flush(); + return stringStream.str(); +} + +int LinkedGraph::totalEdgeMetric() { + int result = 0; + for (int i = 0; i < nodes->getSize(); i++) { + for (int k = 0; k < nodes->get(i)->getSize(); k++) { + result += nodes->get(i)->get(k)->metric; + } + } + result >>= 1; + return result; +} + +bool LinkedGraph::containsEdge(int from, int to) { + if (from < nodes->getSize() && to < nodes->getSize() + && from >= 0 && to >= 0 + && from != to) { + LinkedList* adjacencyList = nodes->get(from); + for (int i = 0; i < adjacencyList->getSize(); i++) { + if (adjacencyList->get(i)->originNode == to + || adjacencyList->get(i)->destinationNode == to) { + return true; + } + } + } + return false; +} diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraph.hpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraph.hpp new file mode 100644 index 000000000..a5eb13bd2 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraph.hpp @@ -0,0 +1,27 @@ +#ifndef MST_LINKEDGRAPH_HPP_ +#define MST_LINKEDGRAPH_HPP_ + +#include +#include "ArrayList.hpp" +#include "LinkedList.hpp" +#include "LinkedGraphEdge.hpp" + +class LinkedGraph { + +public: + ArrayList*>* nodes = new ArrayList*>(); + + LinkedGraph() = default; + LinkedGraph(int nodeCount); + ~LinkedGraph() = default; + + void addNodes(int count); + void addEdge(int origin, int destination, int metric); + void clear(); + std::string toString(); + int totalEdgeMetric(); + bool containsEdge(int from, int to); + +}; + +#endif //MST_LINKEDGRAPH_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraphEdge.cpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraphEdge.cpp new file mode 100644 index 000000000..05b020bb6 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraphEdge.cpp @@ -0,0 +1,7 @@ +#include "LinkedGraphEdge.hpp" + +LinkedGraphEdge::LinkedGraphEdge(int origin, int destination, int metric) { + originNode = origin; + destinationNode = destination; + this->metric = metric; +} diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraphEdge.hpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraphEdge.hpp new file mode 100644 index 000000000..b4808f349 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedGraphEdge.hpp @@ -0,0 +1,17 @@ +#ifndef MST_LINKEDGRAPHEDGE_HPP_ +#define MST_LINKEDGRAPHEDGE_HPP_ + +class LinkedGraphEdge { + +public: + int originNode; + int destinationNode; + int metric; + + LinkedGraphEdge() = default; + LinkedGraphEdge(int origin, int destination, int metric); + ~LinkedGraphEdge() = default; + +}; + +#endif //MST_LINKEDGRAPHEDGE_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedList.cpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedList.cpp new file mode 100644 index 000000000..be133c338 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedList.cpp @@ -0,0 +1,209 @@ +#include +#include +#include +#include "LinkedGraphEdge.hpp" +#include "LinkedListElement.hpp" +#include "LinkedList.hpp" + +template +LinkedList::LinkedList() { + this->size = 0u; + this->firstElement = nullptr; + this->lastElement = nullptr; +} + +template +LinkedList::~LinkedList() { + LinkedListElement* element = firstElement; + LinkedListElement* nextElement = nullptr; + while (element != nullptr) { + nextElement = element->getNextElement(); + delete element; + element = nextElement; + } +} + +template +int LinkedList::getSize() { + return this->size; +} + +template +T LinkedList::get(int index) { + if (index < this->size && index >= 0) { + if (index <= this->size >> 1) { + LinkedListElement *elementPointer = this->firstElement; + for (int i = 0; i < index; i++) + elementPointer = elementPointer->getNextElement(); + return elementPointer->getValue(); + } + else { + LinkedListElement *elementPointer = this->lastElement; + for (int i = this->size - 1; i > index; i--) + elementPointer = elementPointer->getPreviousElement(); + return elementPointer->getValue(); + } + } + else + throw std::out_of_range("Index out of bounds"); +} + +template +bool LinkedList::contains(const T value) { + LinkedListElement *elementPointer = firstElement; + for (int i = 0; i < this->size; i++) { + if (elementPointer->getValue() == value) + return true; + elementPointer = elementPointer->getNextElement(); + } + return false; +} + +template +void LinkedList::add(const T value, int index) { + if (index <= this->size && index >= 0) { + LinkedListElement *newElement = new LinkedListElement(value); + if (index == 0u) { + newElement->setNextElement(this->firstElement); + if (this->firstElement != nullptr) + this->firstElement->setPreviousElement(newElement); + else + this->lastElement = newElement; + this->firstElement = newElement; + } + else { + LinkedListElement *elementBefore; + if (index <= this->size >> 1) { + elementBefore = this->firstElement; + for (int i = 1; i < index; i++) + elementBefore = elementBefore->getNextElement(); + } + else { + elementBefore = this->lastElement; + for (int i = this->size; i > index; i--) + elementBefore = elementBefore->getPreviousElement(); + } + LinkedListElement *elementAfter = elementBefore->getNextElement(); + newElement->setPreviousElement(elementBefore); + newElement->setNextElement(elementAfter); + elementBefore->setNextElement(newElement); + if (elementAfter != nullptr) + elementAfter->setPreviousElement(newElement); + else + this->lastElement = newElement; + } + this->size++; + } + else + throw std::out_of_range("Index out of bounds"); +} + +template +void LinkedList::add(const T value) { + LinkedListElement *newElement = new LinkedListElement(value, this->lastElement, nullptr); + if (this->lastElement != nullptr) + this->lastElement->setNextElement(newElement); + else + this->firstElement = newElement; + this->lastElement = newElement; + this->size++; +} + +template +void LinkedList::addStart(const T value) { + add(value, 0u); +} + +template +void LinkedList::addEnd(const T value) { + add(value); +} + +template +void LinkedList::removeAt(int index) { + if (index < this->size && index >= 0) { + LinkedListElement *elementPointer; + if (index <= this->size >> 1) { + elementPointer = this->firstElement; + for (int i = 0; i < index; i++) + elementPointer = elementPointer->getNextElement(); + } + else { + elementPointer = this->lastElement; + for (int i = this->size - 1; i > index; i--) + elementPointer = elementPointer->getPreviousElement(); + } + remove(elementPointer); + } + else + throw std::out_of_range("Index out of bounds"); +} + +template +void LinkedList::removeFirst() { + if (getSize() > 0) + remove(this->firstElement); + else + throw std::out_of_range("LinkedList is empty"); +} + +template +void LinkedList::removeLast() { + if (getSize() > 0) + remove(this->lastElement); + else + throw std::out_of_range("LinkedList is empty"); +} + +template +void LinkedList::remove(const T value) { + LinkedListElement *elementPointer = this->firstElement; + for (int i = 0; i < this->size; i++) { + if (elementPointer->getValue() == value) { + remove(elementPointer); + return; + } + elementPointer = elementPointer->getNextElement(); + } +} + +template +void LinkedList::print() { + print(false); +} + +template +void LinkedList::print(bool biDirectional) { + LinkedListElement *element = this->firstElement; + while (element != nullptr) { + std::cout << element->getValue() << " "; + element = element->getNextElement(); + } + std::cout << "\n"; + if (biDirectional) { + element = this->lastElement; + while (element != nullptr) { + std::cout << element->getValue() << " "; + element = element->getPreviousElement(); + } + std::cout << "\n"; + } +} + +template +void LinkedList::remove(LinkedListElement* element) { + LinkedListElement *elementBefore = element->getPreviousElement(); + LinkedListElement *elementAfter = element->getNextElement(); + if (elementBefore != nullptr) + elementBefore->setNextElement(elementAfter); + else + this->firstElement = elementAfter; + if (elementAfter != nullptr) + elementAfter->setPreviousElement(elementBefore); + else + this->lastElement = elementBefore; + delete element; + this->size--; +} + +template class LinkedList; diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedList.hpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedList.hpp new file mode 100644 index 000000000..8cdae2e66 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedList.hpp @@ -0,0 +1,37 @@ +#ifndef MST_LINKEDLIST_HPP_ +#define MST_LINKEDLIST_HPP_ + +#include "LinkedListElement.hpp" + +template +class LinkedList { + +private: + LinkedListElement * firstElement; + LinkedListElement * lastElement; + int size; + +public: + LinkedList(); + ~LinkedList(); + + int getSize(); + T get(int index); + bool contains(T const value); + void add(T const value, int index); + void add(T const value); + void addStart(T const value); + void addEnd(T const value); + void removeAt(int index); + void removeFirst(); + void removeLast(); + void remove(T const value); + void print(); + void print(bool biDirectional); + +protected: + void remove(LinkedListElement* element); + +}; + +#endif //MST_LINKEDLIST_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedListElement.cpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedListElement.cpp new file mode 100644 index 000000000..a1ffdd3d4 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedListElement.cpp @@ -0,0 +1,43 @@ +#include "LinkedGraphEdge.hpp" +#include "LinkedListElement.hpp" + +template +LinkedListElement::LinkedListElement(T const value) { + this->value = value; + this->previous = nullptr; + this->next = nullptr; +} + +template +LinkedListElement::LinkedListElement(T const value, LinkedListElement * previous, LinkedListElement * next) { + this->value = value; + this->previous = previous; + this->next = next; +} + +template +T LinkedListElement::getValue() { + return this->value; +} + +template +LinkedListElement * LinkedListElement::getPreviousElement() { + return this->previous; +} + +template +LinkedListElement * LinkedListElement::getNextElement() { + return this->next; +} + +template +void LinkedListElement::setPreviousElement(LinkedListElement * element) { + this->previous = element; +} + +template +void LinkedListElement::setNextElement(LinkedListElement * element) { + this->next = element; +} + +template class LinkedListElement; diff --git a/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedListElement.hpp b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedListElement.hpp new file mode 100644 index 000000000..548a96907 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/data-structures/LinkedListElement.hpp @@ -0,0 +1,25 @@ +#ifndef MST_LINKEDLISTELEMENT_HPP_ +#define MST_LINKEDLISTELEMENT_HPP_ + +template +class LinkedListElement { + +private: + T value; + LinkedListElement * previous; + LinkedListElement * next; + +public: + LinkedListElement(T const value); + LinkedListElement(T const value, LinkedListElement * previous, LinkedListElement * next); + ~LinkedListElement() = default; + + T getValue(); + LinkedListElement * getPreviousElement(); + LinkedListElement * getNextElement(); + void setPreviousElement(LinkedListElement * element); + void setNextElement(LinkedListElement * element); + +}; + +#endif //MST_LINKEDLISTELEMENT_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/kruskal.cpp b/Graphs/Minimum Spanning Tree/C++/kruskal.cpp new file mode 100644 index 000000000..95c228c0b --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/kruskal.cpp @@ -0,0 +1,49 @@ +#include +#include "data-structures/LinkedGraph.hpp" + +LinkedGraph* findMstKruskal(LinkedGraph& graph) { + ArrayList*>* nodes = graph.nodes; + + LinkedGraph* result = new LinkedGraph(nodes->getSize()); + int treeId[nodes->getSize()]; + for (int i = 0; i < nodes->getSize(); i++) { + treeId[i] = i; + } + int trees = nodes->getSize(); + LinkedList remainingEdges = LinkedList(); + for (int i = 0; i < nodes->getSize(); i++) { + for (int k = 0; k < nodes->get(i)->getSize(); k++) { + if (!remainingEdges.contains(nodes->get(i)->get(k))) { + remainingEdges.add(nodes->get(i)->get(k)); + } + } + } + + while (trees > 1 && remainingEdges.getSize() > 0) { + int lowestMetric = std::numeric_limits::max(); + LinkedGraphEdge* lowestMetricEdge = nullptr; + + for (int i = 0; i < remainingEdges.getSize(); i++) { + LinkedGraphEdge* edge = remainingEdges.get(i); + if (edge->metric < lowestMetric) { + lowestMetric = edge->metric; + lowestMetricEdge = edge; + } + } + + if (lowestMetricEdge != nullptr) { + remainingEdges.remove(lowestMetricEdge); + if (treeId[lowestMetricEdge->originNode] != treeId[lowestMetricEdge->destinationNode]) { + result->addEdge(lowestMetricEdge->originNode, lowestMetricEdge->destinationNode, lowestMetricEdge->metric); + int mergedTreeId = treeId[lowestMetricEdge->destinationNode]; + for (int i = 0; i < nodes->getSize(); i++) { + if (treeId[i] == mergedTreeId) { + treeId[i] = treeId[lowestMetricEdge->originNode]; + } + } + --trees; + } + } + } + return result; +} diff --git a/Graphs/Minimum Spanning Tree/C++/kruskal.hpp b/Graphs/Minimum Spanning Tree/C++/kruskal.hpp new file mode 100644 index 000000000..f50c69d2c --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/kruskal.hpp @@ -0,0 +1,6 @@ +#ifndef MST_KRUSKAL_HPP_ +#define MST_KRUSKAL_HPP_ + +LinkedGraph* findMstKruskal(LinkedGraph& graph); + +#endif //MST_KRUSKAL_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/mst.cpp b/Graphs/Minimum Spanning Tree/C++/mst.cpp new file mode 100644 index 000000000..4ed7bc6c6 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/mst.cpp @@ -0,0 +1,134 @@ +#include +#include +#include +#include "data-structures/LinkedGraph.hpp" +#include "prim.hpp" +#include "kruskal.hpp" +#include "nanoseconds.hpp" +#include "mst.hpp" + +int main(int argc, char** argv) { + LinkedGraph graph = LinkedGraph(); + promptGraphGenerationParams(graph); + std::cout << "\n"; + std::cout << "Generated graph:\n"; + printGraph(graph); + std::cout << "Minimum spanning tree, DJP algorithm:\n"; + runPrim(graph); + std::cout << "Minimum spanning tree, Kruskal's algorithm:\n"; + runKruskal(graph); + return 0; +} + +void promptGraphGenerationParams(LinkedGraph& graph) { + std::cout << "Enter number of nodes: "; + int nodeCount = 0; + std::scanf("%d", &nodeCount); + + if (nodeCount <= 0) { + std::cout << "Size of 0 chosen, structure unaltered.\n"; + return; + } + + std::cout << "Enter density [%]: "; + int densityPercentage = 0; + std::scanf("%d", &densityPercentage); + + if (densityPercentage < 0 || densityPercentage > 100) { + std::cerr << "Invalid percentage\n"; + return; + } + + generateRandomGraph(graph, nodeCount, densityPercentage); +} + +void generateRandomGraph(LinkedGraph& graph, int nodeCount, int densityPercentage) { + if (nodeCount > 0 && densityPercentage >= 0 && densityPercentage <= 100) { + graph.clear(); + graph.addNodes(nodeCount); + + std::random_device randomDevice; + std::mt19937 mt = std::mt19937(randomDevice()); + std::uniform_int_distribution nodeDist = std::uniform_int_distribution(0, nodeCount - 1); + std::bernoulli_distribution directionDist = std::bernoulli_distribution(); + std::uniform_int_distribution metricDist = std::uniform_int_distribution(1, MAX_RANDOM_METRIC); + /* + * This part guarantees that we generate a connected graph + */ + bool nodeIncluded[nodeCount] = {}; // { false, ... } + nodeIncluded[nodeDist(mt)] = true; + + for (int i = 1; i < nodeCount; i++) { + int node = nodeDist(mt); + while (nodeIncluded[node]) { + node = nodeDist(mt); + } + int connectionNode = nodeDist(mt); + while (!nodeIncluded[connectionNode]) { + connectionNode = nodeDist(mt); + } + nodeIncluded[node] = true; + if (directionDist(mt)) { + std::swap(node, connectionNode); + } + int metric = metricDist(mt); + graph.addEdge(node, connectionNode, metric); + } + /***/ + + double initialDensity = ((double)nodeCount - 1.0) / (((double)nodeCount - 1.0) * (double)nodeCount); + double probability = (((double) densityPercentage / 100.0) - initialDensity) / (1.0 - initialDensity); + if (densityPercentage > 0) { + std::bernoulli_distribution boolDist = std::bernoulli_distribution(probability); + + for (int i = 0; i < nodeCount; i++) { + for (int k = 0; k < nodeCount; k++) { + if (k != i + && !graph.containsEdge(i, k) + && boolDist(mt)) { + int metric = metricDist(mt); + graph.addEdge(i, k, metric); + } + } + } + } + } +} + +void printGraph(LinkedGraph& graph) { + std::cout << graph.toString() << "\n"; +} + +void runPrim(LinkedGraph& graph) { + std::chrono::time_point timeBefore; + std::chrono::time_point timeAfter; + + timeBefore = std::chrono::high_resolution_clock::now(); + + LinkedGraph* mst = findMstPrim(graph); + + timeAfter = std::chrono::high_resolution_clock::now(); + + std::cout << mst->toString(); + std::cout << "Total edge metric: " << mst->totalEdgeMetric() << "\n"; + delete mst; + + std::cout << "Computation took " << nanoseconds(timeBefore, timeAfter) << " ns\n\n"; +} + +void runKruskal(LinkedGraph& graph) { + std::chrono::time_point timeBefore; + std::chrono::time_point timeAfter; + + timeBefore = std::chrono::high_resolution_clock::now(); + + LinkedGraph* mst = findMstKruskal(graph); + + timeAfter = std::chrono::high_resolution_clock::now(); + + std::cout << mst->toString(); + std::cout << "Total edge metric: " << mst->totalEdgeMetric() << "\n"; + delete mst; + + std::cout << "Computation took " << nanoseconds(timeBefore, timeAfter) << " ns\n\n"; +} diff --git a/Graphs/Minimum Spanning Tree/C++/mst.hpp b/Graphs/Minimum Spanning Tree/C++/mst.hpp new file mode 100644 index 000000000..f6d1c7c0d --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/mst.hpp @@ -0,0 +1,14 @@ +#ifndef MST_HPP_ +#define MST_HPP_ + +#include "data-structures/LinkedGraph.hpp" + +#define MAX_RANDOM_METRIC 1<<10 + +void promptGraphGenerationParams(LinkedGraph& graph); +void generateRandomGraph(LinkedGraph& graph, int nodeCount, int densityPercentage); +void printGraph(LinkedGraph& graph); +void runPrim(LinkedGraph& graph); +void runKruskal(LinkedGraph& graph); + +#endif //MST_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/nanoseconds.hpp b/Graphs/Minimum Spanning Tree/C++/nanoseconds.hpp new file mode 100644 index 000000000..737368fec --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/nanoseconds.hpp @@ -0,0 +1,10 @@ +#ifndef MST_NANOSECONDS_HPP_ +#define MST_NANOSECONDS_HPP_ + +#include + +inline long long int nanoseconds(std::chrono::time_point & since, std::chrono::time_point & until) { + return std::chrono::duration_cast(until - since).count(); +} + +#endif //MST_NANOSECONDS_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C++/prim.cpp b/Graphs/Minimum Spanning Tree/C++/prim.cpp new file mode 100644 index 000000000..622b5cbcd --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/prim.cpp @@ -0,0 +1,50 @@ +#include +#include "data-structures/LinkedGraph.hpp" + +LinkedGraph* findMstPrim(LinkedGraph& graph) { + ArrayList*>* nodes = graph.nodes; + + LinkedGraph* result = new LinkedGraph(nodes->getSize()); + bool nodeIncluded[nodes->getSize()] = {}; // { false ... } + + int cheapestConnectionMetric[nodes->getSize()]; + std::fill_n(cheapestConnectionMetric, nodes->getSize(), std::numeric_limits::max()); + LinkedGraphEdge* cheapestConnectionEdge[nodes->getSize()]; + std::fill_n(cheapestConnectionEdge, nodes->getSize(), nullptr); + + int currentNode = 0; + for (int nodesRemaining = nodes->getSize(); nodesRemaining > 0 && currentNode != -1; nodesRemaining--) { + nodeIncluded[currentNode] = true; + if (cheapestConnectionEdge[currentNode] != nullptr) { + LinkedGraphEdge* edge = cheapestConnectionEdge[currentNode]; + result->addEdge(edge->originNode, edge->destinationNode, edge->metric); + } + + for (int i = 0; i < nodes->get(currentNode)->getSize(); i++) { + LinkedGraphEdge* edge = nodes->get(currentNode)->get(i); + if (edge->originNode == currentNode + && !nodeIncluded[edge->destinationNode] + && edge->metric < cheapestConnectionMetric[edge->destinationNode]) { + cheapestConnectionMetric[edge->destinationNode] = edge->metric; + cheapestConnectionEdge[edge->destinationNode] = edge; + } + else if (edge->destinationNode == currentNode + && !nodeIncluded[edge->originNode] + && edge->metric < cheapestConnectionMetric[edge->originNode]) { + cheapestConnectionMetric[edge->originNode] = edge->metric; + cheapestConnectionEdge[edge->originNode] = edge; + } + } + + int lowestMetric = std::numeric_limits::max(); + int lowestMetricNode = -1; + for (int i = 0; i < nodes->getSize(); i++) { + if (!nodeIncluded[i] && cheapestConnectionMetric[i] < lowestMetric) { + lowestMetric = cheapestConnectionMetric[i]; + lowestMetricNode = i; + } + } + currentNode = lowestMetricNode; + } + return result; +} diff --git a/Graphs/Minimum Spanning Tree/C++/prim.hpp b/Graphs/Minimum Spanning Tree/C++/prim.hpp new file mode 100644 index 000000000..4558331d1 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C++/prim.hpp @@ -0,0 +1,6 @@ +#ifndef MST_PRIM_HPP_ +#define MST_PRIM_HPP_ + +LinkedGraph* findMstPrim(LinkedGraph& graph); + +#endif //MST_PRIM_HPP_ diff --git a/Graphs/Minimum Spanning Tree/C/mst-prims.c b/Graphs/Minimum Spanning Tree/C/mst-prims.c new file mode 100644 index 000000000..210f404c0 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/C/mst-prims.c @@ -0,0 +1,102 @@ +// A C program for Prim's Minimum +// Spanning Tree (MST) algorithm. The program is +// for adjacency matrix representation of the graph +#include +#include +#include +// Number of vertices in the graph +#define V 5 + +// A utility function to find the vertex with +// minimum key value, from the set of vertices +// not yet included in MST +int minKey(int key[], bool mstSet[]) +{ + // Initialize min value + int min = INT_MAX, min_index; + + for (int v = 0; v < V; v++) + if (mstSet[v] == false && key[v] < min) + min = key[v], min_index = v; + + return min_index; +} + +// A utility function to print the +// constructed MST stored in parent[] +int printMST(int parent[], int graph[V][V]) +{ + printf("Edge \tWeight\n"); + for (int i = 1; i < V; i++) + printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]); +} + +// Function to construct and print MST for +// a graph represented using adjacency +// matrix representation +void primMST(int graph[V][V]) +{ + // Array to store constructed MST + int parent[V]; + // Key values used to pick minimum weight edge in cut + int key[V]; + // To represent set of vertices not yet included in MST + bool mstSet[V]; + + // Initialize all keys as INFINITE + for (int i = 0; i < V; i++) + key[i] = INT_MAX, mstSet[i] = false; + + // Always include first 1st vertex in MST. + // Make key 0 so that this vertex is picked as first vertex. + key[0] = 0; + parent[0] = -1; // First node is always root of MST + + // The MST will have V vertices + for (int count = 0; count < V - 1; count++) { + // Pick the minimum key vertex from the + // set of vertices not yet included in MST + int u = minKey(key, mstSet); + + // Add the picked vertex to the MST Set + mstSet[u] = true; + + // Update key value and parent index of + // the adjacent vertices of the picked vertex. + // Consider only those vertices which are not + // yet included in MST + for (int v = 0; v < V; v++) + + // graph[u][v] is non zero only for adjacent vertices of m + // mstSet[v] is false for vertices not yet included in MST + // Update the key only if graph[u][v] is smaller than key[v] + if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) + parent[v] = u, key[v] = graph[u][v]; + } + + // print the constructed MST + printMST(parent, graph); +} + +// driver program to test above function +int main() +{ + /* Let us create the following graph + 2 3 + (0)--(1)--(2) + | / \ | + 6| 8/ \5 |7 + | / \ | + (3)-------(4) + 9 */ + int graph[V][V] = { { 0, 2, 0, 6, 0 }, + { 2, 0, 3, 8, 5 }, + { 0, 3, 0, 0, 7 }, + { 6, 8, 0, 0, 9 }, + { 0, 5, 7, 9, 0 } }; + + // Print the solution + primMST(graph); + + return 0; +} diff --git a/Graphs/Minimum Spanning Tree/java/MST.java b/Graphs/Minimum Spanning Tree/java/MST.java new file mode 100644 index 000000000..694558432 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/java/MST.java @@ -0,0 +1,112 @@ +import java.util.*; +import java.lang.*; +import java.io.*; + +class MST +{ + // Number of vertices in the graph + private static final int V=5; + + // A utility function to find the vertex with minimum key + // value, from the set of vertices not yet included in MST + int minKey(int key[], Boolean mstSet[]) + { + // Initialize min value + int min = Integer.MAX_VALUE, min_index=-1; + + for (int v = 0; v < V; v++) + if (mstSet[v] == false && key[v] < min) + { + min = key[v]; + min_index = v; + } + + return min_index; + } + + // A utility function to print the constructed MST stored in + // parent[] + void printMST(int parent[], int n, int graph[][]) + { + System.out.println("Edge \tWeight"); + for (int i = 1; i < V; i++) + System.out.println(parent[i]+" - "+ i+"\t"+ + graph[i][parent[i]]); + } + + // Function to construct and print MST for a graph represented + // using adjacency matrix representation + void primMST(int graph[][]) + { + // Array to store constructed MST + int parent[] = new int[V]; + + // Key values used to pick minimum weight edge in cut + int key[] = new int [V]; + + // To represent set of vertices not yet included in MST + Boolean mstSet[] = new Boolean[V]; + + // Initialize all keys as INFINITE + for (int i = 0; i < V; i++) + { + key[i] = Integer.MAX_VALUE; + mstSet[i] = false; + } + + // Always include first 1st vertex in MST. + key[0] = 0; // Make key 0 so that this vertex is + // picked as first vertex + parent[0] = -1; // First node is always root of MST + + // The MST will have V vertices + for (int count = 0; count < V-1; count++) + { + // Pick thd minimum key vertex from the set of vertices + // not yet included in MST + int u = minKey(key, mstSet); + + // Add the picked vertex to the MST Set + mstSet[u] = true; + + // Update key value and parent index of the adjacent + // vertices of the picked vertex. Consider only those + // vertices which are not yet included in MST + for (int v = 0; v < V; v++) + + // graph[u][v] is non zero only for adjacent vertices of m + // mstSet[v] is false for vertices not yet included in MST + // Update the key only if graph[u][v] is smaller than key[v] + if (graph[u][v]!=0 && mstSet[v] == false && + graph[u][v] < key[v]) + { + parent[v] = u; + key[v] = graph[u][v]; + } + } + + // print the constructed MST + printMST(parent, V, graph); + } + + public static void main (String[] args) + { + /* Let us create the following graph + 2 3 + (0)--(1)--(2) + | / \ | + 6| 8/ \5 |7 + | / \ | + (3)-------(4) + 9 */ + MST t = new MST(); + int graph[][] = new int[][] {{0, 2, 0, 6, 0}, + {2, 0, 3, 8, 5}, + {0, 3, 0, 0, 7}, + {6, 8, 0, 0, 9}, + {0, 5, 7, 9, 0}}; + + // Print the solution + t.primMST(graph); + } +} diff --git a/Graphs/Minimum Spanning Tree/python/MST_kruskal.py b/Graphs/Minimum Spanning Tree/python/MST_kruskal.py new file mode 100644 index 000000000..be34dd451 --- /dev/null +++ b/Graphs/Minimum Spanning Tree/python/MST_kruskal.py @@ -0,0 +1,103 @@ +# Python program for Kruskal's algorithm to find +# Minimum Spanning Tree of a given connected, +# undirected and weighted graph + +from collections import defaultdict + +#Class to represent a graph +class Graph: + + def __init__(self,vertices): + self.V= vertices #No. of vertices + self.graph = [] # default dictionary + # to store graph + + + # function to add an edge to graph + def addEdge(self,u,v,w): + self.graph.append([u,v,w]) + + # A utility function to find set of an element i + # (uses path compression technique) + def find(self, parent, i): + if parent[i] == i: + return i + return self.find(parent, parent[i]) + + # A function that does union of two sets of x and y + # (uses union by rank) + def union(self, parent, rank, x, y): + xroot = self.find(parent, x) + yroot = self.find(parent, y) + + # Attach smaller rank tree under root of + # high rank tree (Union by Rank) + if rank[xroot] < rank[yroot]: + parent[xroot] = yroot + elif rank[xroot] > rank[yroot]: + parent[yroot] = xroot + + # If ranks are same, then make one as root + # and increment its rank by one + else : + parent[yroot] = xroot + rank[xroot] += 1 + + # The main function to construct MST using Kruskal's + # algorithm + def KruskalMST(self): + + result =[] #This will store the resultant MST + + i = 0 # An index variable, used for sorted edges + e = 0 # An index variable, used for result[] + + # Step 1: Sort all the edges in non-decreasing + # order of their + # weight. If we are not allowed to change the + # given graph, we can create a copy of graph + self.graph = sorted(self.graph,key=lambda item: item[2]) + + parent = [] ; rank = [] + + # Create V subsets with single elements + for node in range(self.V): + parent.append(node) + rank.append(0) + + # Number of edges to be taken is equal to V-1 + while e < self.V -1 : + + # Step 2: Pick the smallest edge and increment + # the index for next iteration + u,v,w = self.graph[i] + i = i + 1 + x = self.find(parent, u) + y = self.find(parent ,v) + + # If including this edge does't cause cycle, + # include it in result and increment the index + # of result for next edge + if x != y: + e = e + 1 + result.append([u,v,w]) + self.union(parent, rank, x, y) + # Else discard the edge + + # print the contents of result[] to display the built MST + print "Following are the edges in the constructed MST" + for u,v,weight in result: + #print str(u) + " -- " + str(v) + " == " + str(weight) + print ("%d -- %d == %d" % (u,v,weight)) + +# Driver code +g = Graph(4) +g.addEdge(0, 1, 10) +g.addEdge(0, 2, 6) +g.addEdge(0, 3, 5) +g.addEdge(1, 3, 15) +g.addEdge(2, 3, 4) + +g.KruskalMST() + +#This code is contributed by Neelam Yadav diff --git a/Graphs/Prims Algorithm/C++/prims.cpp b/Graphs/Prims Algorithm/C++/prims.cpp new file mode 100644 index 000000000..4ee1988cb --- /dev/null +++ b/Graphs/Prims Algorithm/C++/prims.cpp @@ -0,0 +1,76 @@ +//Take a look at the below mentioned link to know about the algorithm +//https://www.geeksforgeeks.org/prims-minimum-spanning-tree-mst-greedy-algo-5/ + +#include +using namespace std; +#define MAX 999999 +#define MIN -999999 + +int g[1000][1000],d[1000],pi[1000],visited[1000]; + +int getMin(int n) +{ + int i=0,j,min=MAX; + for(i=0;i%d\n",pi[i],i); + int sum=0; + for(i=0;i c[k][sel_edge[0]])): + near[k] = sel_edge[0] + print('Resultant MST: \n', np.matrix(t)) + return mincost + +n = random.randint(5,7) +print('Number of vertices:', n) +max_int = math.inf +e = [[0 for x in range(n)] for y in range(n)] +c = [[max_int for x in range(n)] for y in range(n)] +for i in range(n): + for j in range(n): + if(i < j): + e[i][j]=1 + c[i][j]=float(random.randint(10,50)) + else: + e[i][j]=e[j][i] + c[i][j]=c[j][i] +print('Edge Adjacency Matrix: \n', np.matrix(e)) +print('Cost Adjacency Matrix: \n',np.matrix(c)) +print ('Cost of MST: ', primsAlgo(e,c,n)) diff --git a/Graphs/SPFA/shortest-path-faster-algorithm.cpp b/Graphs/SPFA/shortest-path-faster-algorithm.cpp new file mode 100644 index 000000000..35163bd6b --- /dev/null +++ b/Graphs/SPFA/shortest-path-faster-algorithm.cpp @@ -0,0 +1,81 @@ +//This algorithm does the same thing as bellman ford and has the same time complexity but is constant time faster +//look idk how to do all he fancy struct stuff. so dont complain or just use the bellman ford +#include +using namespace std; +typedef pair ii; +queue q; +const int N=10003; // put number of nodes+3 here PLS CHANGE THIS ACCORDINGLY +int w[N],c2[N];//w is shortest path to a node, c2 is number of time a node has been relaxed +bool c[N];//c is to check whether a certain node is in the queue +vector data [N]; //adjacency list of graph +void edge(int x,int y, int l){ //there is a directed edge from x to y with length l + data[x].push_back(ii (y,l)); +} +void initialize(){//initialize variables, may not be the fastest + memset(c2,0,sizeof(c2)); //i apologize for using memset + memset(c,true,sizeof(c)); + memset(w,63,sizeof(w)); //depends on largest path from 1 node to another IMPORTANT + for (int x=0;x=N) continue; // if n is part of negative weight cycle, ignore + c[n]=true; //mark n is not in queue + l=data[n].size(); //just for constant time improvement + for (int x=0;xw[n]+d){ // if u can be relaxed + w[u]=w[n]+d; //relaxing u + c2[u]++;// count number of time u has been relaxed. as u can only be relaxed N-1 times if its not in negative weight cycle + if (c2[u]==N){ //if n in is negative wieght cycle + bfs(u); //mark all of u neighbours as - INF weight + } + else if (c[u]){ //if u is not in queue + c[u]=false; //mark u is in queue + q.push(u); //push u into queue + } + } + } + } +} +void print(int n){ // print length of shortest path + if (c2[n]>=N){ + printf("-Infinity\n"); //part of negative wieght cycle + } + else if (w[n]==1061109567){ + printf("Impossible\n"); //unreachable form source node + } + else{ + printf("%d\n",w[n]); //else just print its shortest path + } +} +int main(){ // the example graph has 5 nodes and 4 edges + initialize(); //pls initialize or weird stuff might happen + edge(0,1,999); + edge (1,2,-2); + edge(2,1,1); + edge (0,3,2); + SPFA(0); //0 is source node + print(1); + print(3); + print(4); + return 0; +} diff --git a/Graphs/bfs/c/bfs.c b/Graphs/bfs/c/bfs.c new file mode 100644 index 000000000..1559316df --- /dev/null +++ b/Graphs/bfs/c/bfs.c @@ -0,0 +1,156 @@ +#include +#include +#define SIZE 40 +struct queue { + int items[SIZE]; + int front; + int rear; +}; +struct queue* createQueue(); +void enqueue(struct queue* q, int); +int dequeue(struct queue* q); +void display(struct queue* q); +int isEmpty(struct queue* q); +void printQueue(struct queue* q); +struct node +{ + int vertex; + struct node* next; +}; +struct node* createNode(int); +struct Graph +{ + int numVertices; + struct node** adjLists; + int* visited; +}; +struct Graph* createGraph(int vertices); +void addEdge(struct Graph* graph, int src, int dest); +void printGraph(struct Graph* graph); +void bfs(struct Graph* graph, int startVertex); +int main() +{ + struct Graph* graph = createGraph(6); + addEdge(graph, 0, 1); + addEdge(graph, 0, 2); + addEdge(graph, 1, 2); + addEdge(graph, 1, 4); + addEdge(graph, 1, 3); + addEdge(graph, 2, 4); + addEdge(graph, 3, 4); + + bfs(graph, 0); + + return 0; +} +void bfs(struct Graph* graph, int startVertex) { + struct queue* q = createQueue(); + + graph->visited[startVertex] = 1; + enqueue(q, startVertex); + + while(!isEmpty(q)){ + printQueue(q); + int currentVertex = dequeue(q); + printf("Visited %d\n", currentVertex); + + struct node* temp = graph->adjLists[currentVertex]; + + while(temp) { + int adjVertex = temp->vertex; + if(graph->visited[adjVertex] == 0){ + graph->visited[adjVertex] = 1; + enqueue(q, adjVertex); + } + temp = temp->next; + } + } +} + +struct node* createNode(int v) +{ + struct node* newNode = malloc(sizeof(struct node)); + newNode->vertex = v; + newNode->next = NULL; + return newNode; +} + +struct Graph* createGraph(int vertices) +{ + struct Graph* graph = malloc(sizeof(struct Graph)); + graph->numVertices = vertices; + + graph->adjLists = malloc(vertices * sizeof(struct node*)); + graph->visited = malloc(vertices * sizeof(int)); + + + int i; + for (i = 0; i < vertices; i++) { + graph->adjLists[i] = NULL; + graph->visited[i] = 0; + } + + return graph; +} + +void addEdge(struct Graph* graph, int src, int dest) +{ + // Add edge from src to dest + struct node* newNode = createNode(dest); + newNode->next = graph->adjLists[src]; + graph->adjLists[src] = newNode; + + // Add edge from dest to src + newNode = createNode(src); + newNode->next = graph->adjLists[dest]; + graph->adjLists[dest] = newNode; +} +struct queue* createQueue() { + struct queue* q = malloc(sizeof(struct queue)); + q->front = -1; + q->rear = -1; + return q; +} +int isEmpty(struct queue* q) { + if(q->rear == -1) + return 1; + else + return 0; +} +void enqueue(struct queue* q, int value){ + if(q->rear == SIZE-1) + printf("\nQueue is Full!!"); + else { + if(q->front == -1) + q->front = 0; + q->rear++; + q->items[q->rear] = value; + } +} +int dequeue(struct queue* q){ + int item; + if(isEmpty(q)){ + printf("Queue is empty"); + item = -1; + } + else{ + item = q->items[q->front]; + q->front++; + if(q->front > q->rear){ + printf("Resetting queue"); + q->front = q->rear = -1; + } + } + return item; +} +void printQueue(struct queue *q) { + int i = q->front; + if(isEmpty(q)) { + printf("Queue is empty"); + } else { + printf("\nQueue contains \n"); + for(i = q->front; i < q->rear + 1; i++) { + printf("%d ", q->items[i]); + } + } +} diff --git a/graph/bfs/cpp/bfs.cpp b/Graphs/bfs/cpp/bfs.cpp similarity index 100% rename from graph/bfs/cpp/bfs.cpp rename to Graphs/bfs/cpp/bfs.cpp diff --git a/graph/bfs/cpp/iterative_bfs.cpp b/Graphs/bfs/cpp/iterative_bfs.cpp similarity index 100% rename from graph/bfs/cpp/iterative_bfs.cpp rename to Graphs/bfs/cpp/iterative_bfs.cpp diff --git a/graph/bfs/go/bfs.go b/Graphs/bfs/go/bfs.go similarity index 100% rename from graph/bfs/go/bfs.go rename to Graphs/bfs/go/bfs.go diff --git a/Graphs/bfs/java/bfs.java b/Graphs/bfs/java/bfs.java new file mode 100644 index 000000000..f5df41d43 --- /dev/null +++ b/Graphs/bfs/java/bfs.java @@ -0,0 +1,74 @@ +import java.util.*; + +public class bfs { + + private Queue cola; + static ArrayList nodes=new ArrayList(); + static class Nodo + { + int datos; + boolean visitado; + List vecinos; + + Nodo(int datos) + { + this.datos=datos; + this.vecinos=new ArrayList<>(); + + } + public void addVecinos(Nodo nVecino) + { + this.vecinos.add(nVecino); + } + public List getVecninos() { + return vecinos; + } + public void setVecinos(List vecinos) { + this.vecinos = vecinos; + } + } + + public bfs() + { + cola = new LinkedList(); + } + + public void bfs(Nodo nodo) + { + cola.add(nodo); + nodo.visitado=true; + while (!cola.isEmpty()) + { + + Nodo e=cola.remove(); + System.out.print(e.datos + "t"); + List vecinos=e.getVecninos(); + for (int i = 0; i < vecinos.size(); i++) { + Nodo n=vecinos.get(i); + if(n!=null && !n.visitado) + { + cola.add(n); + n.visitado=true; + } + } + + } + } + + public static void main(String arg[]) + { + + Nodo n1 =new Nodo(4); + Nodo n2 =new Nodo(1); + Nodo n3 =new Nodo(2); + Nodo n4 =new Nodo(3); + + n1.addVecinos(n2); + n1.addVecinos(n3); + n2.addVecinos(n4); + n3.addVecinos(n2); + n4.addVecinos(n1); + bfs bfsTest = new bfs(); + bfsTest.bfs(n1); + } +} diff --git a/graph/bfs/javascript/bfs.js b/Graphs/bfs/javascript/bfs.js similarity index 100% rename from graph/bfs/javascript/bfs.js rename to Graphs/bfs/javascript/bfs.js diff --git a/Graphs/bfs/python/bfs.py b/Graphs/bfs/python/bfs.py new file mode 100644 index 000000000..92a79027f --- /dev/null +++ b/Graphs/bfs/python/bfs.py @@ -0,0 +1,112 @@ +class Graph: + def __init__(self): + self.nodes = {} + + def insertNode(self, u): + if u not in self.nodes: + self.nodes[u] = {} + + def V(self): + return self.nodes.keys() + + def adj(self, u): + if u in self.nodes: + return self.nodes[u] + + def insertEdge(self, u, v, w=0): + if u not in self.nodes: + self.insertNode(u) + if v not in self.nodes: + self.insertNode(v) + self.nodes[u][v] = w + self.nodes[v][u] = w + + def bfs(self, start): + S = [start] + visited = {} + for node in self.V(): + visited[node] = False + visited[start] = True + while len(S) > 0: + u = S.pop(0) + for v in self.adj(u): + print "Start \t", u, " | Destination:\t", v + if not visited[v]: + visited[v] = True + S.append(v) + + def __str__(self): + string = "" + for u in self.V(): + string += (str(u) + "->" + str(self.adj(u)) + "\n") + return string + + +class OrientedGraph: + def __init__(self): + self.nodes = {} + + def insertNode(self, u): + if u not in self.nodes: + self.nodes[u] = {} + + def V(self): + return self.nodes.keys() + + def adj(self, u): + if u in self.nodes: + return self.nodes[u] + + def insertEdge(self, u, v, w=0): + if u not in self.nodes: + self.insertNode(u) + if v not in self.nodes: + self.insertNode(v) + self.nodes[u][v] = w + + def bfs(self, start): + S = [start] + visited = {} + for node in self.V(): + visited[node] = False + visited[start] = True + while len(S) > 0: + u = S.pop(0) + for v in self.adj(u): + print "Start \t", u, " | Destination:\t", v, " | Cost:\t", self.nodes[u][v] + if not visited[v]: + visited[v] = True + S.append(v) + + def __str__(self): + string = "" + for u in self.V(): + string += (str(u) + "->" + str(self.adj(u)) + "\n") + return string + + +def init(): + print "Test for non-oriented graph" + graph = Graph() + for u in ['a', 'b', 'c', 'd', 'e', 'f']: + graph.insertNode(u) + for u, v in [('a', 'b'), ('a', 'd'), ('b', 'c'), ('d', 'a'), ('d', 'c'), ('d', 'e'), ('e', 'c'), ('e', 'f')]: + graph.insertEdge(u, v) + print str(graph) + # Test bfs starting from a + graph.bfs('a') + print "---------------------------------------------" + print "\nTest for Oriented Graph" + graph = Graph() + for u in ['a', 'b', 'c', 'd', 'e', 'f']: + graph.insertNode(u) + for u, v, w in [('a', 'b', 3), ('a', 'd', 2), ('b', 'c', 0), ('d', 'a', 1), ('d', 'c', 6), ('d', 'e', 10), ('e', 'c', 1), ('e', 'f', 0)]: + graph.insertEdge(u, v, w) + print str(graph) + # Test bellman starting from a + graph.bfs('a') + return + + +if __name__ == '__main__': + init() diff --git a/graph/bfs/ruby/bfs.rb b/Graphs/bfs/ruby/bfs.rb similarity index 100% rename from graph/bfs/ruby/bfs.rb rename to Graphs/bfs/ruby/bfs.rb diff --git a/graph/bfs/ruby/bfs_test.rb b/Graphs/bfs/ruby/bfs_test.rb similarity index 100% rename from graph/bfs/ruby/bfs_test.rb rename to Graphs/bfs/ruby/bfs_test.rb diff --git a/Graphs/check bipartite/Python/checkBipartite.py b/Graphs/check bipartite/Python/checkBipartite.py new file mode 100644 index 000000000..b9c574cb3 --- /dev/null +++ b/Graphs/check bipartite/Python/checkBipartite.py @@ -0,0 +1,72 @@ +# Python program to find out whether a +# given graph is Bipartite or not + +class Graph(): + + def __init__(self, V): + self.V = V + self.graph = [[0 for column in range(V)] \ + for row in range(V)] + + # This function returns true if graph G[V][V] + # is Bipartite, else false + def isBipartite(self, src): + + # Create a color array to store colors + # assigned to all veritces. Vertex + # number is used as index in this array. + # The value '-1' of colorArr[i] is used to + # indicate that no color is assigned to + # vertex 'i'. The value 1 is used to indicate + # first color is assigned and value 0 + # indicates second color is assigned. + colorArr = [-1] * self.V + + # Assign first color to source + colorArr[src] = 1 + + # Create a queue (FIFO) of vertex numbers and + # enqueue source vertex for BFS traversal + queue = [] + queue.append(src) + + # Run while there are vertices in queue + # (Similar to BFS) + while queue: + + u = queue.pop() + + # Return false if there is a self-loop + if self.graph[u][u] == 1: + return False; + + for v in range(self.V): + + # An edge from u to v exists and destination + # v is not colored + if self.graph[u][v] == 1 and colorArr[v] == -1: + + # Assign alternate color to this + # adjacent v of u + colorArr[v] = 1 - colorArr[u] + queue.append(v) + + # An edge from u to v exists and destination + # v is colored with same color as u + elif self.graph[u][v] == 1 and colorArr[v] == colorArr[u]: + return False + + # If we reach here, then all adjacent + # vertices can be colored with alternate + # color + return True + +# Driver program to test above function +g = Graph(4) +g.graph = [[0, 1, 0, 1], + [1, 0, 1, 0], + [0, 1, 0, 1], + [1, 0, 1, 0] + ] + +print "Yes" if g.isBipartite(0) else "No" diff --git a/graph/check bipartite/cpp/CheckBipartite.cpp b/Graphs/check bipartite/cpp/CheckBipartite.cpp similarity index 100% rename from graph/check bipartite/cpp/CheckBipartite.cpp rename to Graphs/check bipartite/cpp/CheckBipartite.cpp diff --git a/Graphs/dfs/c/dfs.c b/Graphs/dfs/c/dfs.c new file mode 100644 index 000000000..80977a7c1 --- /dev/null +++ b/Graphs/dfs/c/dfs.c @@ -0,0 +1,101 @@ +#include +#include + +struct node +{ + int vertex; + struct node* next; +}; +struct node* createNode(int v); +struct Graph +{ + int numVertices; + int* visited; + struct node** adjLists; // we need int** to store a two dimensional array. Similary, we need struct node** to store an array of Linked lists +}; +struct Graph* createGraph(int); +void addEdge(struct Graph*, int, int); +void printGraph(struct Graph*); +void DFS(struct Graph*, int); +int main() +{ + struct Graph* graph = createGraph(4); + addEdge(graph, 0, 1); + addEdge(graph, 0, 2); + addEdge(graph, 1, 2); + addEdge(graph, 2, 3); + + printGraph(graph); + DFS(graph, 2); + + return 0; +} +void DFS(struct Graph* graph, int vertex) { + struct node* adjList = graph->adjLists[vertex]; + struct node* temp = adjList; + + graph->visited[vertex] = 1; + printf("Visited %d \n", vertex); + + while(temp!=NULL) { + int connectedVertex = temp->vertex; + + if(graph->visited[connectedVertex] == 0) { + DFS(graph, connectedVertex); + } + temp = temp->next; + } +} + +struct node* createNode(int v) +{ + struct node* newNode = malloc(sizeof(struct node)); + newNode->vertex = v; + newNode->next = NULL; + return newNode; +} +struct Graph* createGraph(int vertices) +{ + struct Graph* graph = malloc(sizeof(struct Graph)); + graph->numVertices = vertices; + + graph->adjLists = malloc(vertices * sizeof(struct node*)); + + graph->visited = malloc(vertices * sizeof(int)); + + int i; + for (i = 0; i < vertices; i++) { + graph->adjLists[i] = NULL; + graph->visited[i] = 0; + } + return graph; +} + +void addEdge(struct Graph* graph, int src, int dest) +{ + // Add edge from src to dest + struct node* newNode = createNode(dest); + newNode->next = graph->adjLists[src]; + graph->adjLists[src] = newNode; + + // Add edge from dest to src + newNode = createNode(src); + newNode->next = graph->adjLists[dest]; + graph->adjLists[dest] = newNode; +} + +void printGraph(struct Graph* graph) +{ + int v; + for (v = 0; v < graph->numVertices; v++) + { + struct node* temp = graph->adjLists[v]; + printf("\n Adjacency list of vertex %d\n ", v); + while (temp) + { + printf("%d -> ", temp->vertex); + temp = temp->next; + } + printf("\n"); + } +} diff --git a/graph/dfs/cpp/dfs.cpp b/Graphs/dfs/cpp/dfs.cpp similarity index 100% rename from graph/dfs/cpp/dfs.cpp rename to Graphs/dfs/cpp/dfs.cpp diff --git a/graph/dfs/go/dfs.go b/Graphs/dfs/go/dfs.go similarity index 100% rename from graph/dfs/go/dfs.go rename to Graphs/dfs/go/dfs.go diff --git a/graph/dfs/javascript/dfs.js b/Graphs/dfs/javascript/dfs.js similarity index 100% rename from graph/dfs/javascript/dfs.js rename to Graphs/dfs/javascript/dfs.js diff --git a/graph/dfs/python/dfs.py b/Graphs/dfs/python/dfs.py similarity index 100% rename from graph/dfs/python/dfs.py rename to Graphs/dfs/python/dfs.py diff --git a/graph/dfs/ruby/dfs.rb b/Graphs/dfs/ruby/dfs.rb similarity index 100% rename from graph/dfs/ruby/dfs.rb rename to Graphs/dfs/ruby/dfs.rb diff --git a/graph/dfs/ruby/dfs_test.rb b/Graphs/dfs/ruby/dfs_test.rb similarity index 100% rename from graph/dfs/ruby/dfs_test.rb rename to Graphs/dfs/ruby/dfs_test.rb diff --git a/Graphs/disjoint-sets/union-find.cpp b/Graphs/disjoint-sets/union-find.cpp new file mode 100644 index 000000000..ff26ac5a6 --- /dev/null +++ b/Graphs/disjoint-sets/union-find.cpp @@ -0,0 +1,44 @@ +#include +using namespace std; + +#define SizeNodes 10 +#define INF 1e8 + +vector adj[SizeNodes]; +int id[SizeNodes], size[SizeNodes]; + +void init(int i){ + id[i] = i; + size[i] = 1; +} + +int find(int i){ + if(id[i] == i) return i; + return id[i] = find(id[i]); +} + +void unionSet(int a, int b){ + a = find(a); + b = find(b); + + if(a == b) return; + + if(size[a] > size[b]) swap(a, b); + + id[a] = b; + size[b] += size[a]; +} + +int main(){ + for(int i = 0; i < SizeNodes; i++) + init(i); + + unionSet(1, 3); + unionSet(3, 7); + + unionSet(0, 5); + + cout << find(7) << " " << find(0) << endl; + +return 0; +} diff --git a/Graphs/ford-fulkerson/max_flow.cpp b/Graphs/ford-fulkerson/max_flow.cpp new file mode 100644 index 000000000..3c4f8af3f --- /dev/null +++ b/Graphs/ford-fulkerson/max_flow.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +using namespace std; + +// Number of vertices in given graph +#define V 6 + +/* Returns true if there is a path from source 's' to sink 't' in + residual graph. Also fills parent[] to store the path */ +bool bfs(int rGraph[V][V], int s, int t, int parent[]) +{ + // Create a visited array and mark all vertices as not visited + bool visited[V]; + memset(visited, 0, sizeof(visited)); + + // Create a queue, enqueue source vertex and mark source vertex + // as visited + queue q; + q.push(s); + visited[s] = true; + parent[s] = -1; + + // Standard BFS Loop + while (!q.empty()) + { + int u = q.front(); + q.pop(); + + for (int v=0; v 0) + { + q.push(v); + parent[v] = u; + visited[v] = true; + } + } + } + + // If we reached sink in BFS starting from source, then return + // true, else false + return (visited[t] == true); +} + +// Returns the maximum flow from s to t in the given graph +int fordFulkerson(int graph[V][V], int s, int t) +{ + int u, v; + + // Create a residual graph and fill the residual graph with + // given capacities in the original graph as residual capacities + // in residual graph + int rGraph[V][V]; // Residual graph where rGraph[i][j] indicates + // residual capacity of edge from i to j (if there + // is an edge. If rGraph[i][j] is 0, then there is not) + for (u = 0; u < V; u++) + for (v = 0; v < V; v++) + rGraph[u][v] = graph[u][v]; + + int parent[V]; // This array is filled by BFS and to store path + + int max_flow = 0; // There is no flow initially + + // Augment the flow while tere is path from source to sink + while (bfs(rGraph, s, t, parent)) + { + // Find minimum residual capacity of the edges along the + // path filled by BFS. Or we can say find the maximum flow + // through the path found. + int path_flow = INT_MAX; + for (v=t; v!=s; v=parent[v]) + { + u = parent[v]; + path_flow = min(path_flow, rGraph[u][v]); + } + + // update residual capacities of the edges and reverse edges + // along the path + for (v=t; v != s; v=parent[v]) + { + u = parent[v]; + rGraph[u][v] -= path_flow; + rGraph[v][u] += path_flow; + } + + // Add path flow to overall flow + max_flow += path_flow; + } + + // Return the overall flow + return max_flow; +} + +// Driver program to test above functions +int main() +{ + // Let us create a graph shown in the above example + int graph[V][V] = { {0, 16, 13, 0, 0, 0}, + {0, 0, 10, 12, 0, 0}, + {0, 4, 0, 0, 14, 0}, + {0, 0, 9, 0, 0, 20}, + {0, 0, 0, 7, 0, 4}, + {0, 0, 0, 0, 0, 0} + }; + + cout << "The maximum possible flow is " << fordFulkerson(graph, 0, 5); + + return 0; +} diff --git a/Graphs/ford-fulkerson/python/max_flow.py b/Graphs/ford-fulkerson/python/max_flow.py new file mode 100644 index 000000000..8e4fa3785 --- /dev/null +++ b/Graphs/ford-fulkerson/python/max_flow.py @@ -0,0 +1,98 @@ +# Python program for implementation of Ford Fulkerson algorithm + +from collections import defaultdict + +#This class represents a directed graph using adjacency matrix representation +class Graph: + + def __init__(self,graph): + self.graph = graph # residual graph + self. ROW = len(graph) + #self.COL = len(gr[0]) + + + '''Returns true if there is a path from source 's' to sink 't' in + residual graph. Also fills parent[] to store the path ''' + def BFS(self,s, t, parent): + + # Mark all the vertices as not visited + visited =[False]*(self.ROW) + + # Create a queue for BFS + queue=[] + + # Mark the source node as visited and enqueue it + queue.append(s) + visited[s] = True + + # Standard BFS Loop + while queue: + + #Dequeue a vertex from queue and print it + u = queue.pop(0) + + # Get all adjacent vertices of the dequeued vertex u + # If a adjacent has not been visited, then mark it + # visited and enqueue it + for ind, val in enumerate(self.graph[u]): + if visited[ind] == False and val > 0 : + queue.append(ind) + visited[ind] = True + parent[ind] = u + + # If we reached sink in BFS starting from source, then return + # true, else false + return True if visited[t] else False + + + # Returns tne maximum flow from s to t in the given graph + def FordFulkerson(self, source, sink): + + # This array is filled by BFS and to store path + parent = [-1]*(self.ROW) + + max_flow = 0 # There is no flow initially + + # Augment the flow while there is path from source to sink + while self.BFS(source, sink, parent) : + + # Find minimum residual capacity of the edges along the + # path filled by BFS. Or we can say find the maximum flow + # through the path found. + path_flow = float("Inf") + s = sink + while(s != source): + path_flow = min (path_flow, self.graph[parent[s]][s]) + s = parent[s] + + # Add path flow to overall flow + max_flow += path_flow + + # update residual capacities of the edges and reverse edges + # along the path + v = sink + while(v != source): + u = parent[v] + self.graph[u][v] -= path_flow + self.graph[v][u] += path_flow + v = parent[v] + + return max_flow + + +# Create a graph given in the above diagram + +graph = [[0, 16, 13, 0, 0, 0], + [0, 0, 10, 12, 0, 0], + [0, 4, 0, 0, 14, 0], + [0, 0, 9, 0, 0, 20], + [0, 0, 0, 7, 0, 4], + [0, 0, 0, 0, 0, 0]] + +g = Graph(graph) + +source = 0; sink = 5 + +print ("The maximum possible flow is %d " % g.FordFulkerson(source, sink)) + +#This code is contributed by Neelam Yadav diff --git a/graph/graph coloring/square_grid_multidim.cpp b/Graphs/graph coloring/square_grid_multidim.cpp similarity index 100% rename from graph/graph coloring/square_grid_multidim.cpp rename to Graphs/graph coloring/square_grid_multidim.cpp diff --git a/Graphs/knowledge_graph.py b/Graphs/knowledge_graph.py new file mode 100644 index 000000000..98bcb12cc --- /dev/null +++ b/Graphs/knowledge_graph.py @@ -0,0 +1,76 @@ +import webbrowser +import spacy +nlp = spacy.load('en_core_web_sm') +from py2neo import Node, Relationship, Graph + + +## Importing the data +with open ("umls/entities.txt", "r") as myfile: + entities = myfile.readlines() +for i in range(len(entities)): + entities[i] = entities[i].split() + +with open ("umls/entity_category.txt", "r") as myfile: + entity_category = myfile.readlines() +for i in range(len(entity_category)): + entity_category[i] = entity_category[i].split() + +with open ("umls/relations.txt", "r") as myfile: + relations = myfile.readlines() +for i in range(len(relations)): + relations[i] = relations[i].split() + + +with open ("umls/triples.txt", "r") as myfile: + triples = myfile.readlines() +for i in range(len(triples)): + triples[i] = triples[i].split() + +## getting entity_to_id and id_to_entity +entity_to_id = {} +id_to_entity = {} +for i in entities: + entity_to_id[i[1]] = i[0] + id_to_entity[i[0]] = i[1] + +## getting category_to_id and id_to_category +category_to_id = {} +id_to_category = {} +for i in entity_category: + category_to_id[i[1]] = i[0] + id_to_category[i[0]] = i[1] + +## getting relation_to_id and id_to_relation +relation_to_id = {} +id_to_relation = {} +for i in relations: + relation_to_id[i[1]] = i[0] + id_to_relation[i[0]] = i[1] + +## Creating Nodes +nodes_e = [] +nodes_c = [] +for i in range(len(entities)): + nodes_e.append(Node('Entity',name = entities[i][1],id_e = entity_to_id[entities[i][1]])) +for i in range(len(entity_category)): + nodes_c.append(Node('Category',name = entity_category[i][1],id_c = category_to_id[entity_category[i][1]])) + +relationships = [] +for i in triples: + relationship = Relationship(nodes_e[int(i[1])],id_to_relation[i[0]].replace('-','_'),nodes_e[int(i[2])]) + relationships.append(relationship) + +# CReating the graph +graph =Graph(host='localhost',user='neo4j', password=None) # initial graph from the data +#graph = Graph('bolt://neo4j:test@127.0.0.1:7687/db/data') +tx = graph.begin() + +for node in nodes_e: + tx.create(node) +for relationship in relationships: + tx.create(relationship) + +tx.commit() + +#url = 'http://localhost:7474' +#webbrowser.open(url, new=2) # new=2 opens a new tab diff --git a/graph/kruskal/Java/KruskalAlgo.java b/Graphs/kruskal/Java/KruskalAlgo.java similarity index 100% rename from graph/kruskal/Java/KruskalAlgo.java rename to Graphs/kruskal/Java/KruskalAlgo.java diff --git a/Graphs/kruskal/Kruskal.py b/Graphs/kruskal/Kruskal.py new file mode 100644 index 000000000..146237b71 --- /dev/null +++ b/Graphs/kruskal/Kruskal.py @@ -0,0 +1,62 @@ +import math, random +import numpy as np + +def find(b, c): + for a in visited: + if (b in a) and (c in a): + return False + else: + return True + +n = random.randint(5,7) +print('Number of vertices:', n) +max_int = math.inf +num, m, l = 0, 0, 0 +e = [[0 for x in range(n)] for y in range(n)] +c = [[max_int for x in range(n)] for y in range(n)] +t = [[0 for x in range(2)] for y in range(n-1)] +print (np.matrix(t)) +for i in range(n): + for j in range(n): + if(i < j): + e[i][j]=1 + c[i][j]=float(random.randint(10,50)) + else: + e[i][j]=e[j][i] + c[i][j]=c[j][i] + +print('Edge Adjacency Matrix: \n', np.matrix(e)) +print('Cost Adjacency Matrix: \n',np.matrix(c)) +mincost = 0 +visited = [set() for _ in range(n)] +new_set = set() +for i in visited: + i.add(num) + num += 1 +print ('Disjoint Sets: ', visited) +values = np.array(c) +count = 0 +while(count < n-1): + index = np.argmin(values) + u, v = index//n, index%n + if find(u, v): + t[count][0], t[count][1] = u, v + values[u][v], values[v][u] = max_int, max_int + for a in visited: + if u in a: + k = a + if v in a: + l = a + visited.append(k.union(l)) + visited.remove(k) + visited.remove(l) + mincost += c[u][v] + count += 1 +if (count != n-1): + print ('No MST was formed.') + +print ('MST: \n', np.matrix(t)) +print ('Visited:', visited) +print ('Cost:', mincost) + + diff --git a/graph/kruskal/cpp/Kruskal.cpp b/Graphs/kruskal/cpp/Kruskal.cpp similarity index 100% rename from graph/kruskal/cpp/Kruskal.cpp rename to Graphs/kruskal/cpp/Kruskal.cpp diff --git a/graph/topologicalSort/topologicalSort.cpp b/Graphs/topologicalSort/topologicalSort.cpp similarity index 100% rename from graph/topologicalSort/topologicalSort.cpp rename to Graphs/topologicalSort/topologicalSort.cpp diff --git a/Greedy Algorithms/Activity Selection/C/activitysel.c b/Greedy Algorithms/Activity Selection/C/activitysel.c new file mode 100644 index 000000000..caf5fd7c4 --- /dev/null +++ b/Greedy Algorithms/Activity Selection/C/activitysel.c @@ -0,0 +1,28 @@ +#include +#include + +void activities(int s[], int f[], int n) +{ + int i, j; + printf ("Selected Activities are:\n"); + i = 1; + printf("A%d ", i); + for (j = 1; j < n; j++) + { + if (s[j] >= f[i]) + { + printf ("A%d ", j+1); + i = j; + } + } +} +void main() +{ + int s[] = {1, 3, 0, 5, 3, 5, 6, 8, 8, 2, 12}; + int f[] = {4, 5, 6, 7, 9, 9, 10, 11, 12, 14, 16}; + int n = sizeof(s)/sizeof(s[0]); + clrscr(); + activities(s, f, n); + getchar(); + getch(); +} diff --git a/Greedy Algorithms/Activity Selection/cpp/activity_selection.cpp b/Greedy Algorithms/Activity Selection/cpp/activity_selection.cpp new file mode 100644 index 000000000..3fd4b25b7 --- /dev/null +++ b/Greedy Algorithms/Activity Selection/cpp/activity_selection.cpp @@ -0,0 +1,41 @@ +#include +using namespace std; + +struct Activitiy +{ + int start, finish; +}; + + +bool activityCompare(Activitiy s1, Activitiy s2) +{ + return (s1.finish < s2.finish); +} + + +void printMaxActivities(Activitiy arr[], int n) +{ + sort(arr, arr+n, activityCompare); + + cout << "Following activities are selected n"; + int i = 0; + cout << "(" << arr[i].start << ", " << arr[i].finish << "), "; + for (int j = 1; j < n; j++) + { + if (arr[j].start >= arr[i].finish) + { + cout << "(" << arr[j].start << ", " + << arr[j].finish << "), "; + i = j; + } + } +} + +int main() +{ + Activitiy arr[] = {{5, 9}, {1, 2}, {3, 4}, {0, 6}, + {5, 7}, {8, 9}}; + int n = sizeof(arr)/sizeof(arr[0]); + printMaxActivities(arr, n); + return 0; +} diff --git a/Greedy Algorithms/Activity Selection/python/activity_selection.py b/Greedy Algorithms/Activity Selection/python/activity_selection.py new file mode 100644 index 000000000..96161150f --- /dev/null +++ b/Greedy Algorithms/Activity Selection/python/activity_selection.py @@ -0,0 +1,35 @@ + + +class Activity: + + def __init__(self, start, finish): + self.start = start + self.finish = finish + + def __lt__(self, other): + return self.finish < other.finish + + def __repr__(self): + return "( %s, %s )" % (self.start, self.finish) + + +def activity_selection(activity_arr): + selected_activities = [] + + if activity_arr: + activity_arr.sort() + selected = activity_arr[0] + + selected_activities.append(selected) + + for activity in activity_arr: + if activity.start >= selected.finish: + selected = activity + selected_activities.append(selected) + + return selected_activities + + +activity_arr = [Activity(5,9), Activity(1, 2), Activity(3, 4), Activity(0, 6), Activity(5, 7), Activity(8, 9)] + +print(activity_selection(activity_arr)) diff --git a/Greedy Algorithms/Dijkstra Shortest Path/dijkstra-shortest-path.cpp b/Greedy Algorithms/Dijkstra Shortest Path/dijkstra-shortest-path.cpp new file mode 100644 index 000000000..160c68805 --- /dev/null +++ b/Greedy Algorithms/Dijkstra Shortest Path/dijkstra-shortest-path.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +using namespace std; + +typedef pair ii; +typedef vector vi; +typedef vector vii; + +using namespace std; + +int n, m, S, T, w; + +vector AdjList; +vi dist; +priority_queue, greater> pq; + +void dijkstra(int s) +{ + + dist.assign(n, 1e9); + dist[s] = 0; + + pq.push(ii(0, s)); + + while (!pq.empty()) + { + ii front = pq.top(); pq.pop(); + int d = front.first, u = front.second; + if (d > dist[u]) + continue; + for (int j = 0; j < (int)AdjList[u].size(); j++) + { + ii v = AdjList[u][j]; + if (dist[u] + v.second < dist[v.first]) + { + dist[v.first] = dist[u] + v.second; + pq.push(ii(dist[v.first], v.first)); + } + } + } + + if (dist[T] == 1e9) + cout << "unreachable" << endl; + else + cout << dist[T] << endl; +} + +int main() +{ + int numCases; + cin >> numCases; + while (numCases--) + { + scanf("%d %d %d %d", &n, &m, &S, &T); + + AdjList.assign(n, vii()); + + int n1, n2; + for (int i = 0; i < m; i++) + { + scanf("%d %d %d", &n1, &n2, &w); + AdjList[n1].push_back(ii(n2, w)); + AdjList[n2].push_back(ii(n1, w)); + } + dijkstra(S); + } + + return 0; +} diff --git a/Greedy Algorithms/Egyptian fraction b/Greedy Algorithms/Egyptian fraction new file mode 100644 index 000000000..5e192417a --- /dev/null +++ b/Greedy Algorithms/Egyptian fraction @@ -0,0 +1,54 @@ +// C++ program to print a fraction in Egyptian Form using Greedy +// Algorithm +#include +using namespace std; + +void printEgyptian(int nr, int dr) +{ + // If either numerator or denominator is 0 + if (dr == 0 || nr == 0) + return; + + // If numerator divides denominator, then simple division + // makes the fraction in 1/n form + if (dr%nr == 0) + { + cout << "1/" << dr/nr; + return; + } + + // If denominator divides numerator, then the given number + // is not fraction + if (nr%dr == 0) + { + cout << nr/dr; + return; + } + + // If numerator is more than denominator + if (nr > dr) + { + cout << nr/dr << " + "; + printEgyptian(nr%dr, dr); + return; + } + + // We reach here dr > nr and dr%nr is non-zero + // Find ceiling of dr/nr and print it as first + // fraction + int n = dr/nr + 1; + cout << "1/" << n << " + "; + + // Recur for remaining part + printEgyptian(nr*n-dr, dr*n); +} + +// Driver Program +int main() +{ + int nr = 6, dr = 14; + cout << "Egyptian Fraction Representation of " + << nr << "/" << dr << " is\n "; + printEgyptian(nr, dr); + return 0; +} diff --git a/Greedy Algorithms/EqualizingBitStrings/EqualizeBitStrings.cpp b/Greedy Algorithms/EqualizingBitStrings/EqualizeBitStrings.cpp new file mode 100644 index 000000000..155a25a73 --- /dev/null +++ b/Greedy Algorithms/EqualizingBitStrings/EqualizeBitStrings.cpp @@ -0,0 +1,34 @@ +#include + +typedef long long int lli; + +using namespace std; + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + cout.tie(NULL); + cout.precision(50); + string a, b; + lli n, i, x=0; + cin>>n>>a>>b; + for(i=0;i + +// Number of vertices in the graph +#define V 4 + +/* Define Infinite as a large enough value. This value will be used + for vertices not connected to each other */ +#define INF 99999 + +// A function to print the solution matrix +void printSolution(int dist[][V]); + +// Solves the all-pairs shortest path problem using Floyd Warshall algorithm +void floydWarshall (int graph[][V]) +{ + /* dist[][] will be the output matrix that will finally have the shortest + distances between every pair of vertices */ + int dist[V][V], i, j, k; + + /* Initialize the solution matrix same as input graph matrix. Or + we can say the initial values of shortest distances are based + on shortest paths considering no intermediate vertex. */ + for (i = 0; i < V; i++) + for (j = 0; j < V; j++) + dist[i][j] = graph[i][j]; + + /* Add all vertices one by one to the set of intermediate vertices. + ---> Before start of an iteration, we have shortest distances between all + pairs of vertices such that the shortest distances consider only the + vertices in set {0, 1, 2, .. k-1} as intermediate vertices. + ----> After the end of an iteration, vertex no. k is added to the set of + intermediate vertices and the set becomes {0, 1, 2, .. k} */ + for (k = 0; k < V; k++) + { + // Pick all vertices as source one by one + for (i = 0; i < V; i++) + { + // Pick all vertices as destination for the + // above picked source + for (j = 0; j < V; j++) + { + // If vertex k is on the shortest path from + // i to j, then update the value of dist[i][j] + if (dist[i][k] + dist[k][j] < dist[i][j]) + dist[i][j] = dist[i][k] + dist[k][j]; + } + } + } + + // Print the shortest distance matrix + printSolution(dist); +} + +/* A utility function to print solution */ +void printSolution(int dist[][V]) +{ + printf ("The following matrix shows the shortest distances" + " between every pair of vertices \n"); + for (int i = 0; i < V; i++) + { + for (int j = 0; j < V; j++) + { + if (dist[i][j] == INF) + printf("%7s", "INF"); + else + printf ("%7d", dist[i][j]); + } + printf("\n"); + } +} + +// driver program to test above function +int main() +{ + /* Let us create the following weighted graph + 10 + (0)------->(3) + | /|\ + 5 | | + | | 1 + \|/ | + (1)------->(2) + 3 */ + int graph[V][V] = { {0, 5, INF, 10}, + {INF, 0, 3, INF}, + {INF, INF, 0, 1}, + {INF, INF, INF, 0} + }; + + // Print the solution + floydWarshall(graph); + return 0; +} diff --git a/Greedy Algorithms/Fractional Knapsack/java/Fractional_Knapsack.java b/Greedy Algorithms/Fractional Knapsack/java/Fractional_Knapsack.java new file mode 100644 index 000000000..ab0ffa12f --- /dev/null +++ b/Greedy Algorithms/Fractional Knapsack/java/Fractional_Knapsack.java @@ -0,0 +1,63 @@ +import java.util.Scanner; +/** + * @author vrajparesh + * + */ +public class Fractional_Knapsack +{ + private static double getAns(int maxcap, int[] values, int[] weights) + { + double tValue = 0; // Initialize value + double tWeight = 0; // Initialize weight + while (tWeight <= maxcap) + { + int iofMax = HighestVbyW(values, weights); + if (tWeight + weights[iofMax] <= maxcap) + { + tWeight += weights[iofMax]; + tValue += values[iofMax]; + } else + { + double diff = maxcap - tWeight; // Defining a variable that will be fractioned weight, to be added later. + + tWeight += diff; + tValue += diff * (values[iofMax] / (double) weights[iofMax]); + } + values[iofMax] = 0; + if (tWeight == maxcap) + break; + } + return tValue; + } + private static int HighestVbyW(int[] values, int[] weights) + { + double currVal = 0; + double maxVal = 0; + int iofMax = 0; + for (int i = 0; i < values.length; ++i) + { + currVal = values[i] / (double) weights[i]; + if (currVal > maxVal) + { + maxVal = currVal; + iofMax = i; + } + } + return iofMax; + } + public static void main(String args[]) + { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); // Gets number of objects from User + int maxcap = sc.nextInt(); // Gets the Knapsack capacity allowed from user + int[] values = new int[n]; + int[] weights = new int[n]; + for (int i = 0; i < n; i++) + { + values[i] = sc.nextInt(); // Gets the value for the ith object + weights[i] = sc.nextInt(); // Gets the weight for the ith object + } + System.out.println(getAns(maxcap, values, weights)); + sc.close(); + } +} diff --git a/Greedy Algorithms/Fractional Knapsack/python/fractionalKnapsack.py b/Greedy Algorithms/Fractional Knapsack/python/fractionalKnapsack.py new file mode 100644 index 000000000..eba22957e --- /dev/null +++ b/Greedy Algorithms/Fractional Knapsack/python/fractionalKnapsack.py @@ -0,0 +1,43 @@ +# Item class with weight and values +class Item: + # intialize weight and values + def __init__(self, weight=0, value=0): + self.weight = weight + self.value = value + return + + +def fractional_knapsack(items, W): + + # Sorting items by value /weight + sorted(items, key = lambda item: float(item.value)/float(item.weight)) + finalValue = 0.0 + currentWeight = 0 + + for item in items: + + if currentWeight + item.weight <= W : + # If adding Item won't overflow, add it completely + finalValue += item.value + currentWeight += item.weight + + else: + #If we can't add current Item, add a fraction of it + remaining = W - currentWeight + finalValue += item.value*(float(remaining)/float(item.weight)) + break + + return finalValue + +def main(): + W = 50 + items = [ + Item(10, 60), + Item(20, 100), + Item(30, 120) + ] + print("Maximum value we can obtain -{}".format(fractional_knapsack(items, W))) + return + +if __name__ == "__main__": + main() diff --git a/Greedy Algorithms/Gas Station/README.md b/Greedy Algorithms/Gas Station/README.md new file mode 100644 index 000000000..73e81e847 --- /dev/null +++ b/Greedy Algorithms/Gas Station/README.md @@ -0,0 +1,20 @@ +## Description of the problem + +There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. + +You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + +Return the minimum starting gas station’s index if you can travel around the circuit once, otherwise return -1. + +You can only travel in one direction. i to i+1, i+2, ... n-1, 0, 1, 2.. +Completing the circuit means starting at i and ending up at i again. + +Example - +Input : + Gas : [1, 2] + Cost : [2, 1] + +Output : 1 + +If you start from index 0, you can fill in gas[0] = 1 amount of gas. Now your tank has 1 unit of gas. But you need cost[0] = 2 gas to travel to station 1. +If you start from index 1, you can fill in gas[1] = 2 amount of gas. Now your tank has 2 units of gas. You need cost[1] = 1 gas to get to station 0. So, you travel to station 0 and still have 1 unit of gas left over. You fill in gas[0] = 1 unit of additional gas, making your current gas = 2. It costs you cost[0] = 2 to get to station 1, which you do and complete the circuit. \ No newline at end of file diff --git a/Greedy Algorithms/Gas Station/containerShip.cpp b/Greedy Algorithms/Gas Station/containerShip.cpp new file mode 100644 index 000000000..da000267a --- /dev/null +++ b/Greedy Algorithms/Gas Station/containerShip.cpp @@ -0,0 +1,40 @@ +#include +using namespace std; + +int canCompleteCircuit(vector &A, vector &B){ +int n=A.size(); + if(n==1) + return 0; + int sum1=0,sum2=0,i,diff,maxa=0,maxele=0; + for(i=0;i gas,cost; + scanf("%d",&n); + printf("Enter gas at each station\n"); + for(i=0;i +#include +using namespace std; + +struct node{ + + char value; + float freq; + node* right; + node* left; +}; + +struct compare{ + bool operator()(const node &n1, const node &n2) const{ + return n1.freq>n2.freq; + } +}; + + +//IS CORRECT +node * mergeNodes(node *n1, node *n2){ + + node *n=new node; + n->freq=n1->freq+n2->freq; + n->right=n2; + n->left=n1; + n->value='~'; + + return n; +} +void printArr(int arr[], int n){ + for(int i=0; ileft!=NULL){ + arr[top]=0; + codes(root->left, arr, top+1); + } + if(root->right!=NULL){ + arr[top]=1; + codes(root->right, arr, top+1); + } + + if(root->left==NULL && root->left==NULL){ + + cout<value<<"\t : "; + printArr(arr, top); + } + +} + +int main(){ + + string s; + cout<<"Enter String: "; + cin>>s; + int n=s.length(); + priority_queue, compare> pq; + + + for(int i=0; i1){ + n1=new node; + n2=new node; + *n1=pq.top(); + pq.pop(); + *n2=pq.top(); + pq.pop(); + root=mergeNodes(n1,n2); + pq.push(*root); + } + int *arr=new int[100]; + codes(root, arr, 0); + + return 0; +} \ No newline at end of file diff --git a/Greedy Algorithms/Huffman/go/Makefile b/Greedy Algorithms/Huffman/go/Makefile new file mode 100644 index 000000000..09a766b64 --- /dev/null +++ b/Greedy Algorithms/Huffman/go/Makefile @@ -0,0 +1,2 @@ +all: + go build -o huffman diff --git a/Greedy Algorithms/Huffman/go/README.md b/Greedy Algorithms/Huffman/go/README.md new file mode 100644 index 000000000..796badf40 --- /dev/null +++ b/Greedy Algorithms/Huffman/go/README.md @@ -0,0 +1,27 @@ +# Overview + +This is an implementation of Huffman's encryption in go, generating a compression codebook from a byte array. + +## Build + +Simply call + + make + +## Run + +Simply call + + ./huffman + +The result will display the corresponding codebook. + + +## Example + + > huffman aaabccd + 98 b [0 0 1] + 100 d [0 0 0] + 97 a [1] + 99 c [0 1] + diff --git a/Greedy Algorithms/Huffman/go/huffman.go b/Greedy Algorithms/Huffman/go/huffman.go new file mode 100644 index 000000000..04f214375 --- /dev/null +++ b/Greedy Algorithms/Huffman/go/huffman.go @@ -0,0 +1,120 @@ +package main + +import ( + "sort" +) + +// HuffmanTree is a codification of a Huffman tree. We arbitrary decide that we interpret the left tree as bit 1 and +// the right tree as bit 0. In the right part of the tree we store the values for the level, i.e. the nearer to the +// root on the right side, the higher the frequency of the respective character in the stream. +type HuffmanTree struct { + Value byte + Left *HuffmanTree + Right *HuffmanTree +} + +func (tree HuffmanTree) String() string { + s1 := "" + s2 := "" + v := "" + + if !tree.isLeaf() { + s1 = "right: " + tree.Right.String() + // We assume that we always have a left tree if we have a right tree. + s2 = ", left: " + tree.Left.String() + } else { + v = string(tree.Value) + } + + return "{" + v + s1 + s2 + "}" +} + +func (tree HuffmanTree) isLeaf() bool { + return tree.Right == nil && tree.Left == nil +} + +// GetCodebook returns the codebook for this particular tree. +func (tree HuffmanTree) GetCodebook() map[byte][]int { + m := make(map[byte][]int) + + path := make([]int, 0) + for root := tree; root.Right != nil; root = *root.Left { + curPath := append(path, 1) + m[root.Right.Value] = curPath + path = append(path, 0) + + // If we are at the last two elements, use 0 for the last element with the lowest frequency instead of 1. + if root.Left.Right == nil { + m[root.Left.Value] = path + } + } + + return m +} + +// GenerateHuffmanTree generates a HuffmanTree based on the data passed in the parameter. +func NewHuffmanTree(s []byte) HuffmanTree { + frequencies := ComputeFrequency(s) + byteList := SortFrequencyList(frequencies) + + // Combine single sorted lists to a single binary tree. + root := makeLeaf(byteList[0]) + for _, leafValue := range byteList[1:] { + leaf := makeLeaf(leafValue) + root = combineLeafs(root, leaf) + } + + return root +} + +// makeLeaf generate a single leaf without children. +func makeLeaf(value byte) HuffmanTree { + return HuffmanTree{Value: value} +} + +// combineLeafs combines two trees into a single new one without a value. Note that we intentionally pass parameters +// by value to have 'fresh' trees. +func combineLeafs(left, right HuffmanTree) HuffmanTree { + return HuffmanTree{0, &left, &right} +} + +// SortFrequencyList generates a list of bytes sorted by relative frequency, starting with the smallest ones. +func SortFrequencyList(m map[byte]float32) []byte { + // Convert to array of struct values. + type kv struct { + Key byte + Value float32 + } + var kvs []kv + for k, v := range m { + kvs = append(kvs, kv{k, v}) + } + + // Sort array. + sort.Slice(kvs, func(i, j int) bool { + return kvs[i].Value < kvs[j].Value + }) + + // Convert to byte array. + var result []byte + for _, v := range kvs { + result = append(result, v.Key) + } + return result +} + +// ComputeFrequency computes a relative frequency map of all characters in the array. +func ComputeFrequency(s []byte) map[byte]float32 { + m := make(map[byte]float32) + + // Count absolute number. + for _, v := range s { + m[v]++ + } + // Compute relative number of occurrences. + for k, v := range m { + m[k] = v / float32(len(s)) + } + + return m +} diff --git a/Greedy Algorithms/Huffman/go/huffman_test.go b/Greedy Algorithms/Huffman/go/huffman_test.go new file mode 100644 index 000000000..290760a05 --- /dev/null +++ b/Greedy Algorithms/Huffman/go/huffman_test.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "reflect" + "testing" +) + +func TestFrequencyEmpty(t *testing.T) { + m := ComputeFrequency([]byte("")) + if len(m) != 0 { + t.Error("len is not zero") + } +} + +func TestFrequencySingle(t *testing.T) { + m := ComputeFrequency([]byte("a")) + + if m[byte('a')] != 1.0 { + t.Error("Single frequency should be 1.0") + } +} + +func TestFrequencyMultiple(t *testing.T) { + m := ComputeFrequency([]byte("aba")) + + // If we generalize this, we should use epsilon-based comparison. + if m[byte('a')] != 0.6666667 { + t.Error("'a' frequency should be 0.66 but is", m[byte('a')]) + } + + if m[byte('b')] != 0.33333334 { + t.Error("'b' frequency should be 0.33 but is", m[byte('b')]) + } +} + +func TestSortedFrequencyMultiple(t *testing.T) { + m := ComputeFrequency([]byte("aba")) + s := SortFrequencyList(m) + expected := []byte{98, 97} + for k, v := range s { + if expected[k] != v { + t.Error("Byte ordering by frequency did not work") + } + } +} + +func TestTreeGeneration(t *testing.T) { + tree := NewHuffmanTree([]byte("aaabbc")) + + if tree.Right.Value != byte('a') { + t.Error("Expected a") + } + if tree.Left.Right.Value != byte('b') { + t.Error("Expected b") + } + if tree.Left.Left.Value != byte('c') { + t.Error("Expected c") + } +} + +func TestCodebookGeneration(t *testing.T) { + tree := NewHuffmanTree([]byte("aababcabcd")) + codebook := tree.GetCodebook() + + tests := [][]int{ + {1}, codebook[byte('a')], + {0, 1}, codebook[byte('b')], + {0, 0, 1}, codebook[byte('c')], + {0, 0, 0}, codebook[byte('d')], + } + + for k := 0; k < len(tests); k += 2 { + expected := tests[k] + result := tests[k+1] + if !reflect.DeepEqual(expected, result) { + t.Error("Expected other values!") + fmt.Println("Expected=", expected) + fmt.Println("Result=", result) + } + } +} diff --git a/Greedy Algorithms/Huffman/go/main.go b/Greedy Algorithms/Huffman/go/main.go new file mode 100644 index 000000000..048a68291 --- /dev/null +++ b/Greedy Algorithms/Huffman/go/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "os" + "strings" +) + +func main() { + if len(os.Args) == 1 { + fmt.Println("Usage:", os.Args[0], "") + return + } + + data := strings.Join(os.Args[1:], " ") + tree := NewHuffmanTree([]byte(data)) + codebook := tree.GetCodebook() + for k, v := range codebook { + display := "" + if k > 48 && k < 127 { + display = string(k) + } + fmt.Println(int(k), display, v) + } +} diff --git a/Greedy Algorithms/Kruskal.c b/Greedy Algorithms/Kruskal.c new file mode 100644 index 000000000..b1337bd74 --- /dev/null +++ b/Greedy Algorithms/Kruskal.c @@ -0,0 +1,95 @@ +#include +#define MAX 30 +typedef struct edge +{ + int u,v,w; +}edge; +typedef struct edgelist +{ +edge data[MAX]; + int n; +}edgelist; +edgelist elist; +int G[MAX][MAX],n; +edgelist spanlist; +void kruskal(); +int find(int belongs[],int vertexno); +void union1(int belongs[],int c1,int c2); +void sort(); +void print(); +void main() +{ + int i,j,total_cost; +printf("\nEnter number of vertices:"); +scanf("%d",&n); +printf("\nEnter the adjacency matrix:\n"); + for(i=0;ielist.data[j+1].w) + { + temp=elist.data[j]; + elist.data[j]=elist.data[j+1]; + elist.data[j+1]=temp; + } +} +void print() +{ + int i,cost=0; + for(i=0;i + +typedef long long int lli; + +using namespace std; + +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + cout.tie(NULL); + cout.precision(50); + lli n; + cin >> n; + lli a[n]; + for(int i = 0; i> a[i]; + } + lli ans = 1; + lli out = 1; + for(int i = 1; i a[i-1]) + { + ans++; + } + else + { + ans = 1; + } + out = max(out,ans); + } + cout << out << endl; +} diff --git a/Greedy Algorithms/MaximumIncreasingSubarray/ProblemStatement.md b/Greedy Algorithms/MaximumIncreasingSubarray/ProblemStatement.md new file mode 100644 index 000000000..5e45317db --- /dev/null +++ b/Greedy Algorithms/MaximumIncreasingSubarray/ProblemStatement.md @@ -0,0 +1,5 @@ +### Maximum Increasing Subarray + +You are given array consisting of *n* integers. Your task is to find the maximum length of an increasing subarray of the given array. + +A subarray is the sequence of consecutive elements of the array. Subarray is called increasing if each element of this subarray strictly greater than previous. diff --git a/Greedy Algorithms/egyptian-fraction.cpp b/Greedy Algorithms/egyptian-fraction.cpp new file mode 100644 index 000000000..01b312baf --- /dev/null +++ b/Greedy Algorithms/egyptian-fraction.cpp @@ -0,0 +1,52 @@ +#include +using namespace std; + +void printEgyptian(int nr, int dr) +{ + // If either numerator or denominator is 0 + if (dr == 0 || nr == 0) + return; + + // If numerator divides denominator, then simple division + // makes the fraction in 1/n form + if (dr%nr == 0) + { + cout << "1/" << dr/nr; + return; + } + + // If denominator divides numerator, then the given number + // is not fraction + if (nr%dr == 0) + { + cout << nr/dr; + return; + } + + // If numerator is more than denominator + if (nr > dr) + { + cout << nr/dr << " + "; + printEgyptian(nr%dr, dr); + return; + } + + // We reach here dr > nr and dr%nr is non-zero + // Find ceiling of dr/nr and print it as first + // fraction + int n = dr/nr + 1; + cout << "1/" << n << " + "; + + // Recur for remaining part + printEgyptian(nr*n-dr, dr*n); + } + +// Driver Program +int main() +{ + int nr = 6, dr = 14; + cout << "Egyptian Fraction Representation of " + << nr << "/" << dr << " is\n "; + printEgyptian(nr, dr); + return 0; +} diff --git a/Greedy Algorithms/ford-fulkerson.cpp b/Greedy Algorithms/ford-fulkerson.cpp new file mode 100644 index 000000000..3c4f8af3f --- /dev/null +++ b/Greedy Algorithms/ford-fulkerson.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +using namespace std; + +// Number of vertices in given graph +#define V 6 + +/* Returns true if there is a path from source 's' to sink 't' in + residual graph. Also fills parent[] to store the path */ +bool bfs(int rGraph[V][V], int s, int t, int parent[]) +{ + // Create a visited array and mark all vertices as not visited + bool visited[V]; + memset(visited, 0, sizeof(visited)); + + // Create a queue, enqueue source vertex and mark source vertex + // as visited + queue q; + q.push(s); + visited[s] = true; + parent[s] = -1; + + // Standard BFS Loop + while (!q.empty()) + { + int u = q.front(); + q.pop(); + + for (int v=0; v 0) + { + q.push(v); + parent[v] = u; + visited[v] = true; + } + } + } + + // If we reached sink in BFS starting from source, then return + // true, else false + return (visited[t] == true); +} + +// Returns the maximum flow from s to t in the given graph +int fordFulkerson(int graph[V][V], int s, int t) +{ + int u, v; + + // Create a residual graph and fill the residual graph with + // given capacities in the original graph as residual capacities + // in residual graph + int rGraph[V][V]; // Residual graph where rGraph[i][j] indicates + // residual capacity of edge from i to j (if there + // is an edge. If rGraph[i][j] is 0, then there is not) + for (u = 0; u < V; u++) + for (v = 0; v < V; v++) + rGraph[u][v] = graph[u][v]; + + int parent[V]; // This array is filled by BFS and to store path + + int max_flow = 0; // There is no flow initially + + // Augment the flow while tere is path from source to sink + while (bfs(rGraph, s, t, parent)) + { + // Find minimum residual capacity of the edges along the + // path filled by BFS. Or we can say find the maximum flow + // through the path found. + int path_flow = INT_MAX; + for (v=t; v!=s; v=parent[v]) + { + u = parent[v]; + path_flow = min(path_flow, rGraph[u][v]); + } + + // update residual capacities of the edges and reverse edges + // along the path + for (v=t; v != s; v=parent[v]) + { + u = parent[v]; + rGraph[u][v] -= path_flow; + rGraph[v][u] += path_flow; + } + + // Add path flow to overall flow + max_flow += path_flow; + } + + // Return the overall flow + return max_flow; +} + +// Driver program to test above functions +int main() +{ + // Let us create a graph shown in the above example + int graph[V][V] = { {0, 16, 13, 0, 0, 0}, + {0, 0, 10, 12, 0, 0}, + {0, 4, 0, 0, 14, 0}, + {0, 0, 9, 0, 0, 20}, + {0, 0, 0, 7, 0, 4}, + {0, 0, 0, 0, 0, 0} + }; + + cout << "The maximum possible flow is " << fordFulkerson(graph, 0, 5); + + return 0; +} diff --git a/Greedy Algorithms/graphcolor.cpp b/Greedy Algorithms/graphcolor.cpp new file mode 100644 index 000000000..3deaf4f80 --- /dev/null +++ b/Greedy Algorithms/graphcolor.cpp @@ -0,0 +1,102 @@ +#include +#include +using namespace std; + +// A class that represents an undirected graph +class Graph +{ + int V; // No. of vertices + list *adj; // A dynamic array of adjacency lists +public: + // Constructor and destructor + Graph(int V) { this->V = V; adj = new list[V]; } + ~Graph() { delete [] adj; } + + // function to add an edge to graph + void addEdge(int v, int w); + + // Prints greedy coloring of the vertices + void greedyColoring(); +}; + +void Graph::addEdge(int v, int w) +{ + adj[v].push_back(w); + adj[w].push_back(v); // Note: the graph is undirected +} + +// Assigns colors (starting from 0) to all vertices and prints +// the assignment of colors +void Graph::greedyColoring() +{ + int result[V]; + + // Assign the first color to first vertex + result[0] = 0; + + // Initialize remaining V-1 vertices as unassigned + for (int u = 1; u < V; u++) + result[u] = -1; // no color is assigned to u + + // A temporary array to store the available colors. True + // value of available[cr] would mean that the color cr is + // assigned to one of its adjacent vertices + bool available[V]; + for (int cr = 0; cr < V; cr++) + available[cr] = false; + + // Assign colors to remaining V-1 vertices + for (int u = 1; u < V; u++) + { + // Process all adjacent vertices and flag their colors + // as unavailable + list::iterator i; + for (i = adj[u].begin(); i != adj[u].end(); ++i) + if (result[*i] != -1) + available[result[*i]] = true; + + // Find the first available color + int cr; + for (cr = 0; cr < V; cr++) + if (available[cr] == false) + break; + + result[u] = cr; // Assign the found color + + // Reset the values back to false for the next iteration + for (i = adj[u].begin(); i != adj[u].end(); ++i) + if (result[*i] != -1) + available[result[*i]] = false; + } + + // print the result + for (int u = 0; u < V; u++) + cout << "Vertex " << u << " ---> Color " + << result[u] << endl; +} + +// Driver program to test above function +int main() +{ + Graph g1(5); + g1.addEdge(0, 1); + g1.addEdge(0, 2); + g1.addEdge(1, 2); + g1.addEdge(1, 3); + g1.addEdge(2, 3); + g1.addEdge(3, 4); + cout << "Coloring of graph 1 \n"; + g1.greedyColoring(); + + Graph g2(5); + g2.addEdge(0, 1); + g2.addEdge(0, 2); + g2.addEdge(1, 2); + g2.addEdge(1, 4); + g2.addEdge(2, 4); + g2.addEdge(4, 3); + cout << "\nColoring of graph 2 \n"; + g2.greedyColoring(); + + return 0; +} diff --git a/Greedy Algorithms/knapsack.cpp b/Greedy Algorithms/knapsack.cpp new file mode 100644 index 000000000..a01378023 --- /dev/null +++ b/Greedy Algorithms/knapsack.cpp @@ -0,0 +1,63 @@ +#include +using namespace std; +int main() +{ + int array[2][100], n, w, i, curw, used[100], maxi = -1, totalprofit = 0; + //input number of objects + cout << "Enter number of objects: "; + cin >> n; + //input max weight of knapsack + cout << "Enter the weight of the knapsack: "; + cin >> w; + /* Array's first row is to store weights + second row is to store profits */ + for (i = 0; i < n; i++) + { + cin >> array[0][i] >> array[1][i]; + } + for (i = 0; i < n; i++) + { + used[i] = 0; + } + curw = w; + //loop until knapsack is full + while (curw >= 0) + { + maxi = -1; + //loop to find max profit object + for (i = 0; i < n; i++) + { + if ((used[i] == 0) && ((maxi == -1) || (((float) array[1][i] + / (float) array[0][i]) > ((float) array[1][maxi] + / (float) array[0][maxi])))) + { + maxi = i; + } + } + used[maxi] = 1; + //decrease current wight + curw -= array[0][maxi]; + //increase total profit + totalprofit += array[1][maxi]; + if (curw >= 0) + { + cout << "\nAdded object " << maxi + 1 << " Weight: " + << array[0][maxi] << " Profit: " << array[1][maxi] + << " completely in the bag, Space left: " << curw; + } + else + { + cout << "\nAdded object " << maxi + 1 << " Weight: " + << (array[0][maxi] + curw) << " Profit: " + << (array[1][maxi] / array[0][maxi]) * (array[0][maxi] + + curw) << " partially in the bag, Space left: 0" + << " Weight added is: " << curw + array[0][maxi]; + totalprofit -= array[1][maxi]; + totalprofit += ((array[1][maxi] / array[0][maxi]) * (array[0][maxi] + + curw)); + } + } + //print total worth of objects filled in knapsack + cout << "\nBags filled with objects worth: " << totalprofit; + return 0; +} diff --git a/Greedy Algorithms/minimum_number_of_coins.cpp b/Greedy Algorithms/minimum_number_of_coins.cpp index 5f534a52b..52fcb7843 100644 --- a/Greedy Algorithms/minimum_number_of_coins.cpp +++ b/Greedy Algorithms/minimum_number_of_coins.cpp @@ -1,27 +1,27 @@ -#include - using namespace std; - int deno[] = {1, 2, 5, 10, 20, 50, 100, 500, 1000}; //user defined denominations -int n = sizeof(deno)/sizeof(deno[0]); - void minChange(int m) -{ - vector v; - for (int i=n-1; i>=0; i--) - { - while (m>=deno[i]) - { - m-=deno[i]; - v.push_back(deno[i]); - } - } - for (int i = 0; i < v.size(); i++) - cout << v[i] << " "; -} - int main() -{ - int n; - cout<<"Enter a value n for which you want minimal number of change: "<<'\n'; - cin>>n; - cout << "Minimal number of change for " << n << " is "; - minChange(n); - return 0; -} +#include +using namespace std; + +// m is size of coins array (number of different coins) +int minCoins(int coins[], int m, int V) +{ + // base case + if (V == 0) return 0; + + // Initialize result + int res = INT_MAX; + + // Try every coin that has smaller value than V + for (int i=0; i +#include + +using namespace std; + +struct node +{ + struct node *prev_node; + int info; + struct node *next_node; +}; + +struct node *create_list(struct node *begin); +void display(struct node *begin); +struct node *addtoemptylist(struct node *begin,int data_element); +struct node *addatbeglist(struct node *begin,int data_element); +struct node *addatendlist(struct node *begin,int data_element); +struct node *addafterlist(struct node *begin,int data_element,int item_pos); +struct node *addbeforelist(struct node *begin,int data_element,int item_pos); +struct node *deletenode(struct node *begin,int data_element); +struct node *reverselist(struct node *begin); + +int main() +{ + int option,data_element,item_pos; + struct node *begin=NULL; + while(1) + { + cout<<"\n1.Create A New Doubly Linked List\n"; + cout<<"2.Display the Doubly Linked List\n"; + cout<<"3.Add to an Empty Doubly Linked List\n"; + cout<<"4.Add at Starting of the Doubly Linked List\n"; + cout<<"5.Add at Ending\n"; + cout<<"6.Add After a Node\n"; + cout<<"7.Add Before a Node\n"; + cout<<"8.Delete a Node\n"; + cout<<"9.Reverse the Doubly Linked List\n"; + cout<<"10.Exit\n"; + cout<<"Enter your option : "; + cin>>option; + + switch(option) + { + case 1: + begin=create_list(begin); + break; + case 2: + display(begin); + break; + case 3: + cout<<"Enter the element:"; + cin>>data_element; + begin=addtoemptylist(begin,data_element); + break; + case 4: + cout<<"Enter the element:"; + cin>>data_element; + begin=addatbeglist(begin,data_element); + break; + case 5: + cout<<"Enter the element:"; + cin>>data_element; + begin=addatendlist(begin,data_element); + break; + case 6: + cout<<"Enter the element:"; + cin>>data_element; + cout<<"Enter the element after which to insert : "; + cin>>item_pos; + begin=addafterlist(begin,data_element,item_pos); + break; + case 7: + cout<<"Enter the element: "; + cin>>data_element; + cout<<"Enter the element before which to insert : "; + cin>>item_pos; + begin=addbeforelist(begin,data_element,item_pos); + break; + case 8: + cout<<"Enter the element to be Deleted : "; + cin>>data_element; + begin=deletenode(begin,data_element); + break; + case 9: + begin=reverselist(begin); + break; + case 10: + exit(1); + default: + cout<<"Wrong option\n"; + } + } + + return 0; +} + +struct node *create_list(struct node *begin) +{ + int i,n,data_element; + cout<<"Enter the number of nodes : "; + cin>>n; + begin=NULL; + if(n==0) + return begin; + cout<<"Enter the element: "; + cin>>data_element; + begin=addtoemptylist(begin,data_element); + + for(i=2;i<=n;i++) + { + cout<<"Enter the element to be inserted : "; + cin>>data_element; + begin=addatendlist(begin,data_element); + } + return begin; +} + +void display(struct node *begin) +{ + struct node *p; + if(begin==NULL) + { + cout<<"List is empty\n"; + return; + } + p=begin; + cout<<"List is :\n"; + while(p!=NULL) + { + cout<info<<" "; + p=p->next_node; + } + cout<<"\n"; +} + +struct node *addtoemptylist(struct node *begin,int data_element) +{ + struct node *temp; + temp=new struct node; + temp->info=data_element; + temp->prev_node=NULL; + temp->next_node=NULL; + begin=temp; + return begin; +} +struct node *addatbeglist(struct node *begin,int data_element) +{ + if(begin==NULL) + { + cout<<"List is empty\n"; + return begin; + } + + struct node *temp; + temp = new struct node; + temp->info=data_element; + temp->prev_node=NULL; + temp->next_node=begin; + begin->prev_node=temp; + begin=temp; + return begin; +} + +struct node *addatendlist(struct node *begin,int data_element) +{ + if(begin==NULL) + { + cout<<"List is empty\n"; + return begin; + } + + struct node *temp,*p; + temp=new struct node; + temp->info=data_element; + p=begin; + while(p->next_node!=NULL) + p=p->next_node; + p->next_node=temp; + temp->next_node=NULL; + temp->prev_node=p; + return begin; +} +struct node *addafterlist(struct node *begin,int data_element,int item_pos) +{ + struct node *temp,*p; + temp=new struct node; + temp->info=data_element; + p=begin; + while(p!=NULL) + { + if(p->info==item_pos) + { + temp->prev_node=p; + temp->next_node=p->next_node; + if(p->next_node!=NULL) + p->next_node->prev_node=temp; + p->next_node=temp; + return begin; + } + p=p->next_node; + } + cout<info==item_pos) + { + temp = new struct node; + temp->info=data_element; + temp->prev_node=NULL; + temp->next_node=begin; + begin->prev_node=temp; + begin=temp; + return begin; + } + q=begin; + while(q!=NULL) + { + if(q->info==item_pos) + { + temp=new struct node; + temp->info=data_element; + temp->prev_node=q->prev_node; + temp->next_node = q; + q->prev_node->next_node=temp; + q->prev_node=temp; + return begin; + } + q=q->next_node; + } + cout<next_node==NULL) + if(begin->info==data_element) + { + temp=begin; + begin=NULL; + delete(temp); + return begin; + } + else + { + cout<<"Element "<info==data_element) + { + temp=begin; + begin=begin->next_node; + begin->prev_node=NULL; + delete(temp); + return begin; + } + + temp=begin->next_node; + while(temp->next_node!=NULL ) + { + if(temp->info==data_element) + { + temp->prev_node->next_node=temp->next_node; + temp->next_node->prev_node=temp->prev_node; + delete(temp); + return begin; + } + temp=temp->next_node; + } + + if(temp->info==data_element) + { + temp->prev_node->next_node=NULL; + delete(temp); + return begin; + } + cout<<"Element "<next_node; + p1->next_node=NULL; + p1->prev_node=p2; + while(p2!=NULL) + { + p2->prev_node=p2->next_node; + p2->next_node=p1; + p1=p2; + p2=p2->prev_node; + } + begin=p1; + cout<<"List reverselistd\n"; + return begin; +} diff --git a/LinkedList/C/Doubly_LinkedList/Doubly_Linkedlist.c b/LinkedList/C/Doubly_LinkedList/Doubly_Linkedlist.c new file mode 100755 index 000000000..919cf8f44 --- /dev/null +++ b/LinkedList/C/Doubly_LinkedList/Doubly_Linkedlist.c @@ -0,0 +1,73 @@ +#include +#include +struct node{ +int info; +struct node *prev,*next; +}; +struct node* start=NULL; +void insert() +{ +struct node *n; +n=(struct node *)malloc(sizeof(struct node)); +printf("enter the first info"); +scanf("%d",&n->info); +n->prev=NULL; +n->next=NULL; +if(start==NULL) +start=n; + else + { + start->prev=n; + n->next=start; + start=n; + } +} +void delete() +{ +struct node *r; +if(start==NULL) +printf("linkedlist is empty"); +else +{ +r=start; +start=start->next; +start->prev=NULL; +free(r); +} +} +void view() +{ +struct node *t; +if(start==NULL) +printf("linked list is empty\n"); +else{ +t=start; +while(t->next!=NULL){ +printf("%d ",t->info); +t=t->next; +} +if(t->next==NULL) +printf("%d",t->info); +printf("\n"); +} +} +int main() +{ +int ch; +while(1){ +printf("1.insert\n2.delete\n3.view\n4.exit\n"); +scanf("%d",&ch); +switch(ch) +{ +case 1:insert(); +break; +case 2:delete(); +break; +case 3:view(); +break; +case 4:return 1; +defult:printf("invalid choice\n"); +} +} +return 0; +} diff --git a/LinkedList/C/linkedList.c b/LinkedList/C/linkedList.c new file mode 100644 index 000000000..1cf06c936 --- /dev/null +++ b/LinkedList/C/linkedList.c @@ -0,0 +1,199 @@ +#include +#include + +// Define the node and declare head, temp variables. + +struct node{ + int data; + struct node* link; +}*head, *temp; + +//Function to insert at beginning +void begins(int x){ + struct node* new = (struct node*)malloc(sizeof(struct node)); + new -> data = x; + if (head == NULL){ + head = new; + head -> link = NULL; + return; + } + new -> link = head; + head = new; +} + +//Function to insert at end +void endins(int x){ + struct node *new, *ptr; + new = (struct node*)malloc(sizeof(struct node)); + new -> data = x; + if (head == NULL){ + head = new; + head -> link = NULL; + return; + } + ptr = head; + while(ptr -> link != NULL){ + ptr = ptr -> link; + } + ptr -> link = new; + new -> link = NULL; +} + +//Function to insert at a position +void posins(int x, int pos){ + struct node *new, *ptr; + new = (struct node*)malloc(sizeof(struct node)); + new -> data = x; + if (head == NULL){ + head = new; + head -> link = NULL; + return; + } + ptr = head; + int count = 0; + while(count != pos && ptr -> link != NULL){ + ptr = ptr -> link; + count++; + } + new -> link = ptr -> link; + ptr -> link = new; +} + +//Function to insert before a specific data node +void datains(int x, int data){ + struct node *new, *ptr, *ptr1; + new = (struct node*)malloc(sizeof(struct node)); + new -> data = x; + if (head == NULL){ + head = new; + head -> link = NULL; + return; + } + ptr = head; + while(ptr -> data != data && ptr -> link != NULL){ + ptr1 = ptr; + ptr = ptr -> link; + } + new -> link = ptr; + ptr1 -> link = new; +} + +//Function to delete at beginning +void begdel(){ + if (head == NULL){ + printf("LIST ALREADY EMPTY\n"); + return ; + } + temp = head; + head = head -> link; + free(temp); +} + +//Function to delete at end +void enddel(){ + if (head == NULL){ + printf("LIST ALREADY EMPTY\n"); + return ; + } + struct node* ptr = head; + while(ptr -> link -> link != NULL){ + ptr = ptr -> link; + } + temp = ptr -> link; + ptr -> link = NULL; + free(temp); +} + +//Function to delete at a position +void posdel(int pos){ + if (head == NULL){ + printf("LIST ALREADY EMPTY\n"); + return ; + } + int count = 0; + struct node* ptr = head, *ptr1; + while(count != pos && ptr -> link != NULL){ + ptr1 = ptr; + ptr = ptr -> link; + count++; + } + temp = ptr; + ptr1 -> link = ptr -> link; + free(temp); +} + +//Function to delete before a specific data node +void datadel(int data){ + if (head == NULL){ + printf("LIST ALREADY EMPTY\n"); + return ; + } + struct node* ptr = head, *ptr1; + while(ptr -> link -> data != data && ptr -> link != NULL){ + ptr1 = ptr; + ptr = ptr -> link; + } + temp = ptr; + ptr1 -> link = ptr -> link; + free(temp); +} + +//Function to neatly display the list +void disp(){ + printf("\n======================================================\n"); + struct node* ptr = head; + while (ptr != NULL){ + printf("%d ", ptr -> data); + ptr = ptr -> link; + } + printf("\n======================================================\n"); +} + +int main(){ + int c, x, pos; + while(1){ + printf("1. Beg Ins\n2. End Ins\n3. Beg Del\n4. End Del\n5. Pos Ins\n6. Data Ins\n7. Pos Del\n8. Data Del\nEnter your choice: "); + scanf("%d", &c); + switch(c){ + case 1: printf("Enter the data to be inserted: "); + scanf("%d", &x); + begins(x); + break; + case 2: printf("Enter the data to be inserted: "); + scanf("%d", &x); + endins(x); + break; + case 3: begdel(); + break; + case 4: enddel(); + break; + case 5: printf("Enter the Position and Data: "); + scanf("%d%d", &pos, &x); + if(pos == 0){ + begins(x); + break; + } + posins(x, pos-1); + break; + case 6: printf("Enter the insert-before-data data and data: "); + scanf("%d%d", &pos, &x); + datains(x, pos); + break; + case 8: printf("Enter the delete-before-data data: "); + scanf("%d", &pos); + datadel(pos); + break; + case 7: printf("Enter the Position: "); + scanf("%d", &pos); + if(pos == 0){ + begdel(); + break; + } + posdel(pos-1); + break; + default:printf("INVALID CHOICE\n"); + } + disp(); + } + return 0; +} diff --git a/LinkedList/Java/LinkedList.java b/LinkedList/Java/LinkedList.java new file mode 100644 index 000000000..a8dedfe71 --- /dev/null +++ b/LinkedList/Java/LinkedList.java @@ -0,0 +1,215 @@ +import java.io.InputStreamReader; +import java.util.LinkedList; +import java.util.Scanner; + + +public class LinkedList { + + class Node { + int value; + Node next = null; + Node(int value) { + this.value = value; + } + } + + protected Node head = null; + protected Node tail = null; + + public void addToFront(int value) { + Node newNode = new Node(value); + newNode.next = head; + head = newNode; + if(newNode.next == null) + { + tail = newNode; + } + } + + public void addToBack(int value) { + Node newNode = new Node(value); + if(tail == null) + { + head = newNode; + } + else + { + tail.next = newNode; + } + tail = newNode; + } + + public void addAtIndex(int index,int value) { + if(index < 0) + { + throw new IndexOutOfBoundsException(); + } + else if(index == 0) + { + addToFront(value); + } + else + { + Node newNode = new Node(value); + Node current = head; + for(int i = 0; i < index-1; i++) { + if(current == null) + { + throw new IndexOutOfBoundsException(); + } + current = current.next; + } + if(current.next == null) + { + tail = newNode; + } + else + { + newNode.next = current.next; + current.next = newNode; + } + } + } + + public void removeFromFront() { + if(head != null) + { + head = head.next; + } + if(head == null) + { + tail = null; + } + } + + public void removeFromBack() { + if(head == null) + { + return; + } + else if(head.equals(tail)) + { + head = null; + tail = null; + } + else + { + Node current = head; + while(current.next != tail) { + current = current.next; + } + tail = current; + current.next = null; + } + } + + public void removeAtIndex(int index) { + if(index < 0) + { + throw new IndexOutOfBoundsException(); + } + else if(index == 0) + { + removeFromFront(); + } + else + { + Node current = head; + for(int i = 0; i < index-1; i++) { + if(current == null) + { + throw new IndexOutOfBoundsException(); + } + current = current.next; + } + current.next = current.next.next; + if(current.next == null) + { + tail = current; + } + } + } + + public void printList() { + Node newNode = head; + if(head != null) + { + System.out.println("The Linked List contains :"); + while(newNode != null) { + System.out.println(newNode.value); + newNode = newNode.next; + } + } + else + { + System.out.println("The list contains no elements"); + } + } + + public void count() { + Node newNode=head; + int counter = 0; + while(newNode != null ) { + counter++; + newNode = newNode.next; + } + System.out.println("The list contains "+counter+" elements"); + } + public static void main(String[] args) { + Scanner in=new Scanner(new InputStreamReader(System.in)); + LinkedListeg list = new LinkedListeg(); + int ch = 0; + do { + System.out.println("Choose form the following"); + System.out.println("1.Add to Front\n2.Add to Back\n3.Add at index\n4.Remove from front"); + System.out.println("5.Remove from back\n6.remove at index\n7.Print elements in the Linked List"); + System.out.println("8.Count number of elements in the list\n9.Exit"); + ch = in.nextInt(); + int value = 0; + int index = 0; + switch (ch) { + case 1: + System.out.println("Enter a value"); + value = in.nextInt(); + list.addToFront(value); + break; + case 2: + System.out.println("Enter a value"); + value = in.nextInt(); + list.addToBack(value); + break; + case 3: + System.out.println("Enter a value"); + value = in.nextInt(); + System.out.println("Enter index"); + index = in.nextInt(); + list.addAtIndex(index,value); + break; + case 4: + list.removeFromFront(); + break; + case 5: + list.removeFromBack(); + break; + case 6: + System.out.println("Enter the index"); + index = in.nextInt(); + list.removeAtIndex(index); + break; + case 7: + list.printList(); + break; + case 8: + list.count(); + break; + case 9: + System.exit(0); + break; + default: + System.out.println("Wrong Choice"); + break; + } + System.out.println(); + } while (ch != 9); + } +} diff --git a/LinkedList/LinkList.class b/LinkedList/LinkList.class new file mode 100644 index 000000000..8265dcdaa Binary files /dev/null and b/LinkedList/LinkList.class differ diff --git a/LinkedList/LinkList.java b/LinkedList/LinkList.java new file mode 100644 index 000000000..242b2b514 --- /dev/null +++ b/LinkedList/LinkList.java @@ -0,0 +1,66 @@ +public class LinkList{ + private Node head; + + public void LinkList(){ + head=null; + } + + public void insert(int i){ + Node newNode = new Node(i); + newNode.next = head; + head = newNode; + + System.out.println("New Node Inserted : "+i); + } + + public Node find(int key){ + int i=1; + Node current = null; + + current = head; + + while(current != null && i != key){ + current = current.next; + i++; + } + + return current; + + } + + public void delete(int key){ + Node current = null; + Node previous = null; + + current = head; + previous = head; + + int i = 1; + + while(current.next != null && i != key){ + + previous = current; + current = current.next; + i++; + } + if(current==head){ + head = head.next; + }else{ + previous.next = current.next; + } + System.out.println("Item Deleted"); + } + + public void display(){ + Node current; + + current = head; + + while(current != null){ + System.out.println("Node : "+ current.item); + current = current.next; + } + } + + +} \ No newline at end of file diff --git a/LinkedList/LinkedListModule.py b/LinkedList/LinkedListModule.py new file mode 100644 index 000000000..8e15cb268 --- /dev/null +++ b/LinkedList/LinkedListModule.py @@ -0,0 +1,158 @@ +class Node: + """Class to create nodes for a linked list""" + + def __init__(self,data = None,next = None): + self.data = data + self.next = next + +class LinkedList: + """Class to create the actual linked list with several nodes""" + + def __init__(self): + # initializes the head of the linked list + self.head = None + + def addNodeAtEnd(self,value): + """Adds a node containing given value to the end of the list""" + if self.head is None: + self.head = Node(value) + else: + # iterate to the end of the list and add the node + CurrentNode = self.head + + while CurrentNode.next is not None: + CurrentNode = CurrentNode.next + + CurrentNode.next = Node(value) + + return True + + def addNodeAtBeginning(self,value): + """Adds a node containing given value to the beginning of the list""" + if self.head is None: + self.head = Node(value) + else: + # rearranging the references to the nodes + temp = Node(value) + temp.next = self.head + self.head = temp + + def searchValue(self,value): + """searches for the given value and returns a boolean""" + flag = 0 + + if self.head is None: + return False + else: + CurrentNode = self.head + + while CurrentNode is not None: + if CurrentNode.data == value: + return True + + CurrentNode = CurrentNode.next + + return False + + def printList(self,seperator = ' '): + """simply prints all the elements currently present in the list""" + if self.head is None: + return False + else: + CurrentNode = self.head + + while CurrentNode is not None: + print(CurrentNode.data,end = seperator) + CurrentNode = CurrentNode.next + + print() + + return True + + def deleteNodeByValue(self,value): + """searches for the node containing the value and deletes that node""" + if self.head is None: + return False + elif self.head.data == value: + self.head = self.head.next + return True + else: + CurrentNode = self.head + + while CurrentNode is not None: + if CurrentNode.next.data == value: + CurrentNode.next = CurrentNode.next.next + return True + + CurrentNode = CurrentNode.next + + def deleteNodeByPosition(self,pos): + """deletes a node at the given position""" + if self.head is None: + return False + elif pos == 0: + self.head = self.head.next + return True + else: + CurrentNode = self.head + + while pos > 1: + CurrentNode = CurrentNode.next + pos -= 1 + + CurrentNode.next = CurrentNode.next.next + + return True + + def getLength(self): + """returns the length of the current list""" + if self.head is None: + return 0 + else: + NodeCount = 0 + CurrentNode = self.head + + while CurrentNode is not None: + NodeCount += 1 + CurrentNode = CurrentNode.next + + return NodeCount + + def getMaxElement(self): + """returns the maximum element in the list""" + MaxElement = self.head.data + CurrentNode = self.head + + while CurrentNode is not None: + if MaxElement < CurrentNode.data: + MaxElement = CurrentNode.data + + CurrentNode = CurrentNode.next + + return MaxElement + + def getMinElement(self): + """returns the minimum element in the list""" + MinElement = self.head.data + CurrentNode = self.head + + while CurrentNode is not None: + if MinElement > CurrentNode.data: + MinElement = CurrentNode.data + + CurrentNode = CurrentNode.next + + return MinElement + + def getNodeCount(self,value): + """returns the number of nodes containing a particular value""" + CurrentNode = self.head + NodeCount = 0 + + while CurrentNode is not None: + if CurrentNode.data == value: + NodeCount += 1 + + CurrentNode = CurrentNode.next + + return NodeCount diff --git a/LinkedList/Node.class b/LinkedList/Node.class new file mode 100644 index 000000000..51ef84544 Binary files /dev/null and b/LinkedList/Node.class differ diff --git a/LinkedList/Node.java b/LinkedList/Node.java new file mode 100644 index 000000000..425f33ef1 --- /dev/null +++ b/LinkedList/Node.java @@ -0,0 +1,14 @@ +public class Node{ + + public int item; + public Node next; + + public Node(int i){ + this.item = i; + this.next = null; + } + + public void displayNode(){ + System.out.println(item); + } +} \ No newline at end of file diff --git a/LinkedList/Run.class b/LinkedList/Run.class new file mode 100644 index 000000000..763cb9766 Binary files /dev/null and b/LinkedList/Run.class differ diff --git a/LinkedList/Run.java b/LinkedList/Run.java new file mode 100644 index 000000000..281463c87 --- /dev/null +++ b/LinkedList/Run.java @@ -0,0 +1,21 @@ +public class Run{ + + public static void main(String args[]){ + + LinkList mylist = new LinkList(); + + mylist.insert(10); + mylist.insert(20); + mylist.insert(30); + mylist.display(); + + Node retur = mylist.find(2); + System.out.println(retur.item); + + mylist.delete(2); + mylist.display(); + + mylist.delete(2); + mylist.display(); + } +} \ No newline at end of file diff --git a/Mathematics/Armstrong_no/C/armstrong_no.c b/Mathematics/Armstrong_no/C/armstrong_no.c new file mode 100644 index 000000000..3793766ed --- /dev/null +++ b/Mathematics/Armstrong_no/C/armstrong_no.c @@ -0,0 +1,47 @@ +/** + * C program to check Armstrong number + */ +#include +#include + +int main() +{ + int originalNum, num, lastDigit, digits, sum; + + /* Input number from user */ + printf("Enter any number to check Armstrong number: "); + scanf("%d", &num); + + sum = 0; + + /* Copy the value of num for processing */ + originalNum = num; + + /* Find total digits in num */ + digits = (int) log10(num) + 1; + + /* Calculate sum of power of digits */ + while(num > 0) + { + /* Extract the last digit */ + lastDigit = num % 10; + + /* Compute sum of power of last digit */ + sum = sum + round(pow(lastDigit, digits)); + + /* Remove the last digit */ + num = num / 10; + } + + /* Check for Armstrong number */ + if(originalNum == sum) + { + printf("%d is ARMSTRONG NUMBER", originalNum); + } + else + { + printf("%d is NOT ARMSTRONG NUMBER", originalNum); + } + + return 0; +} diff --git a/Mathematics/Armstrong_no/cpp/armstrong_no.cpp b/Mathematics/Armstrong_no/cpp/armstrong_no.cpp new file mode 100644 index 000000000..610b1fb99 --- /dev/null +++ b/Mathematics/Armstrong_no/cpp/armstrong_no.cpp @@ -0,0 +1,21 @@ +#include +using namespace std; + +int main() +{ + int origNum, num, rem, sum = 0; + cout << "Enter a positive integer: "; + cin >> origNum; + num = origNum; + while(num != 0) + { + rem = num % 10; + sum += rem * rem * rem; + num /= 10; + } + if(sum == origNum) + cout << origNum << " is an Armstrong number."; + else + cout << origNum << " is not an Armstrong number."; + return 0; +} \ No newline at end of file diff --git a/Mathematics/Armstrong_no/javascript/armstrong.js b/Mathematics/Armstrong_no/javascript/armstrong.js new file mode 100644 index 000000000..a5d281a95 --- /dev/null +++ b/Mathematics/Armstrong_no/javascript/armstrong.js @@ -0,0 +1,23 @@ +/** + * An Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits. + * For instance, a 3 digit number will be considered an Armstrong number if the sum of the cubes of its digits is equal to the number itself. + * For example, 153 is an Armstrong number, as 1**3 + 5**3 + 3**3 = 153 + */ + +const armstrongNumber = (num) => { + let sum = 0; + let ar = num.toString().split(""); + for(let i = 0; i 0: + digit = temp % 10 + sum += digit ** 3 + temp //= 10 + +if num == sum: + print(num,"is an Armstrong number") +else: + print(num,"is not an Armstrong number") \ No newline at end of file diff --git a/Mathematics/Check Wagstaff Prime/CPP/Wagstaff.cpp b/Mathematics/Check Wagstaff Prime/CPP/Wagstaff.cpp new file mode 100644 index 000000000..7cc88b9b1 --- /dev/null +++ b/Mathematics/Check Wagstaff Prime/CPP/Wagstaff.cpp @@ -0,0 +1,37 @@ + +#include +using namespace std; + +bool isPrime(int n) +{ + if (n <= 1) + return false; + if (n <= 3) + return true; + if (n % 2 == 0 || n % 3 == 0) + return false; + + for (int i = 5; i * i <= n; i = i + 6) { + if (n % i == 0 || n % (i + 2) == 0) { + return false; + } + } + + return true; +} +bool isPowerOfTwo(int n) +{ + return (n && !(n & (n - 1))); +} +int main() +{ + int n = 43; + if (isPrime(n) && (isPowerOfTwo(n * 3 - 1))) { + cout << "YES\n"; + } + else { + cout << "NO\n"; + } + + return 0; +} diff --git a/Mathematics/GCD/C#/gcd.cs b/Mathematics/GCD/C#/gcd.cs new file mode 100644 index 000000000..26c15d7e3 --- /dev/null +++ b/Mathematics/GCD/C#/gcd.cs @@ -0,0 +1,13 @@ +namespace GCD +{ + class Program + { + public static int gcd(int a, int b) + { + if (b == 0) + return a; + else + return gcd(b, a % b); + } + } +} diff --git a/Mathematics/GCD/C/Makefile b/Mathematics/GCD/C/Makefile new file mode 100644 index 000000000..a6105952f --- /dev/null +++ b/Mathematics/GCD/C/Makefile @@ -0,0 +1,5 @@ +CC=gcc +CFLAGS=-I. + +gcd: gcd.o + $(CC) gcd.c -o gcd diff --git a/Mathematics/GCD/C/gcd.c b/Mathematics/GCD/C/gcd.c new file mode 100644 index 000000000..a82deef44 --- /dev/null +++ b/Mathematics/GCD/C/gcd.c @@ -0,0 +1,15 @@ +#include + +int greatCommonDiv(int a, int b){ //used euclidian method to calculate gcd of two numbers + if(b==0){ + return a; + } + return(greatCommonDiv(b , a%b)); +} +int main(int argc, char const *argv[]) { + +int result=greatCommonDiv(35,45); + +printf("Greatest divider is: %d\n",result); + return 0; +} diff --git a/Mathematics/GCD/cpp/GCDlarge.cpp b/Mathematics/GCD/cpp/GCDlarge.cpp new file mode 100644 index 000000000..767ff698f --- /dev/null +++ b/Mathematics/GCD/cpp/GCDlarge.cpp @@ -0,0 +1,39 @@ +#include +#define MAX 250 + +using namespace std; + +int mod(char*,int); + +int findGCD(int a,char*b){ + int bInt = a; + a = mod(b,a); + while(a != 0){ + int temp = a; + a = bInt%a; + bInt = temp; + } + + return bInt; +} + +int mod(char* b,int a){ + + int x=0; + for(int i=0;b[i]!='\0';i++){ + x = ((x*10) + (b[i]-'0'))%a; + } + return x%a; +} + + +int main() +{ + int a; + char b[MAX]; + cin>>a; + cin>>b; + + cout< +#include + +int size(int a) +{ + int size = 0; + while (a != 0) + { + a /= 10; + size++; + } + return size; +} + +int max(int a, int b) +{ + if (a > b) + return a; + else + return b; +} + +int karatsuba(int a, int b) +{ + if (a < 10 && b < 10) + return a * b; + + int m = max(size(a), size(b)); + int m2 = m/2; + + int high1 = a / ((int) pow(10, m2)); + int low1 = a % ((int) pow(10, m2)); + int high2 = b / ((int) pow(10, m2)); + int low2 = b % ((int) pow(10, m2)); + + int z0 = karatsuba(low1, low2); + int z1 = karatsuba((low1 + high1), (low2 + high2)); + int z2 = karatsuba(high1, high2); + + return (z2 * ((int)pow(10, (m2 * 2)))) + ((z1 - z2 - z0) * ((int)pow(10, m2))) + z0; +} + +int main() +{ + int a, b; + scanf ("%d %d", &a, &b); + printf("%d * %d = %d\n", a, b, karatsuba(a, b)); + return 0; +} diff --git a/Mathematics/LCM/C/lcm.c b/Mathematics/LCM/C/lcm.c new file mode 100644 index 000000000..7574023fd --- /dev/null +++ b/Mathematics/LCM/C/lcm.c @@ -0,0 +1,46 @@ +/** + * C program to find LCM of any two numbers + */ + +#include + +int main() +{ + int i, num1, num2, max, lcm=1; + + /* Input two numbers from user */ + printf("Enter any two numbers to find LCM: "); + scanf("%d%d", &num1, &num2); + + /* Find maximum between num1 and num2 */ + max = (num1 > num2) ? num1 : num2; + + /* First multiple to be checked */ + i = max; + + /* Run loop indefinitely till LCM is found */ + while(1) + { + if(i%num1==0 && i%num2==0) + { + /* + * If 'i' divides both 'num1' and 'num2' + * then 'i' is the LCM. + */ + lcm = i; + + /* Terminate the loop after LCM is found */ + break; + } + + /* + * If LCM is not found then generate next + * multiple of max between both numbers + */ + i += max; + } + + printf("LCM of %d and %d = %d", num1, num2, lcm); + + return 0; +} diff --git a/Mathematics/LCM/CPP/lcm.cpp b/Mathematics/LCM/CPP/lcm.cpp new file mode 100644 index 000000000..5fa31ad0c --- /dev/null +++ b/Mathematics/LCM/CPP/lcm.cpp @@ -0,0 +1,19 @@ +#include + +int gcd(int a, int b){ + if(b == 0) + return a; + return gcd(b, a % b); +} + +int lcm(int a, int b){ + return a * b / gcd(a, b); +} + +int main() +{ + int a{}; + int b{}; + std::cin >> a >> b; + std::cout << lcm(a, b); +} diff --git a/Mathematics/LCM/go/lcm.go b/Mathematics/LCM/go/lcm.go new file mode 100644 index 000000000..3f173c110 --- /dev/null +++ b/Mathematics/LCM/go/lcm.go @@ -0,0 +1,33 @@ +package main + +import( + "fmt" +) + +func gcd (a int, b int) int { + if (b > a){ + return gcd(b,a) + } + if (b == 0){ + return a + } + return gcd(b,a%b) +} +func lcm(a int, b int) int { + var p int = a*b + + return p / gcd(a,b) +} + +func main(){ + var x,y int + + fmt.Println("The Point of this program is to compute", + "LCM.\nPlease enter two numbers space seperated.") + + _,err := fmt.Scanf("%d %d",&x, &y) + if ( (err != nil) || (x|y == 0)){ + fmt.Println("Invalid input") + } + fmt.Printf("LCM of %d,%d is %d\n",x,y,lcm(x,y)) +} diff --git a/Mathematics/LCM/go/src/main.go b/Mathematics/LCM/go/src/main.go new file mode 100644 index 000000000..954bb083b --- /dev/null +++ b/Mathematics/LCM/go/src/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "fmt" +) + +func gcd(a int, b int) int { + if b == 0 { + return a + } + return gcd(b, a%b) +} + +func lcm(a int, b int) int { + return (a * b) / gcd(a, b) +} + +func main() { + a := 0 + b := 0 + fmt.Println("Find LCM") + fmt.Println("Enter a") + fmt.Scanln(&a) + fmt.Println("Enter b") + fmt.Scanln(&b) + + result := lcm(a, b) + fmt.Printf("LCM of %v and %v is %v", a, b, result) +} \ No newline at end of file diff --git a/Mathematics/LCM/python/lcm.py b/Mathematics/LCM/python/lcm.py new file mode 100644 index 000000000..7a2a28897 --- /dev/null +++ b/Mathematics/LCM/python/lcm.py @@ -0,0 +1,13 @@ +import sys + +def findLCM(a, b): + lar = max(a, b) + small = min(a, b) + i = lar + while(1) : + if (i % small == 0): + return i + i += lar + +a,b = map(int, input.split()) +print(findLCM(a, b)) diff --git a/Mathematics/Pollard-Rho/cpp/prime.cpp b/Mathematics/Pollard-Rho/cpp/prime.cpp new file mode 100644 index 000000000..be7cda338 --- /dev/null +++ b/Mathematics/Pollard-Rho/cpp/prime.cpp @@ -0,0 +1,44 @@ +#include +using namespace std; +typedef long long int ll; + +ll modular_pow(long long int base, int exponent, + long long int modulus) { + ll result = 1; + while (exponent > 0) { + if (exponent & 1) + result = (result * base) % modulus; + exponent = exponent >> 1; + base = (base * base) % modulus; + } + return result; +} + + +ll PollardRho(long long int n) { + srand (time(NULL)); + if (n==1) return n; + if (n % 2 == 0) return 2; + ll x = (rand()%(n-2))+2; + ll y = x; + ll c = (rand()%(n-1))+1; + ll d = 1; + + while (d==1) { + x = (modular_pow(x, 2, n) + c + n)%n; + y = (modular_pow(y, 2, n) + c + n)%n; + y = (modular_pow(y, 2, n) + c + n)%n; + d = __gcd(abs(x-y), n); + if (d==n) return PollardRho(n); + } + return d; +} + + +int main() { + ll n; + scanf("%lld", &n); + printf("One of the divisors for %lld is %lld.", + n, PollardRho(n)); + return 0; +} diff --git a/Mathematics/Power_For_Huge_Num/Power_Huge.cpp b/Mathematics/Power_For_Huge_Num/Power_Huge.cpp new file mode 100644 index 000000000..ecfb5ffb5 --- /dev/null +++ b/Mathematics/Power_For_Huge_Num/Power_Huge.cpp @@ -0,0 +1,86 @@ +#include +using namespace std; + +// Maximum number of digits in output +// x^n where 1 <= x, n <= 10000 and overflow may happen +#define MAX 100000 + +// This function multiplies x +// with the number represented by res[]. +// res_size is size of res[] or +// number of digits in the number +// represented by res[]. This function +// uses simple school mathematics +// for multiplication. +// This function may value of res_size +// and returns the new value of res_size +int multiply(int x, int res[], int res_size) { + +// Initialize carry +int carry = 0; + +// One by one multiply n with +// individual digits of res[] +for (int i = 0; i < res_size; i++) { + int prod = res[i] * x + carry; + + // Store last digit of + // 'prod' in res[] + res[i] = prod % 10; + + // Put rest in carry + carry = prod / 10; +} + +// Put carry in res and +// increase result size +while (carry) { + res[res_size] = carry % 10; + carry = carry / 10; + res_size++; +} +return res_size; +} + +// This function finds +// power of a number x +void power(int x, int n) +{ + +//printing value "1" for power = 0 +if(n == 0 ){ + cout<<"1"; + return; +} + + +int res[MAX]; +int res_size = 0; +int temp = x; + +// Initialize result +while (temp != 0) { + res[res_size++] = temp % 10; + temp = temp / 10; +} + +// Multiply x n times +// (x^n = x*x*x....n times) +for (int i = 2; i <= n; i++) + res_size = multiply(x, res, res_size); + +cout << x << "^" << n << " = "; +for (int i = res_size - 1; i >= 0; i--) + cout << res[i]; +} + +// Driver program +int main() { +int exponent, base; +printf("Enter base "); +scanf("%id \n", &base); +printf("Enter exponent "); +scanf("%id", &exponent); +power(base, exponent); +return 0; +} diff --git a/Mathematics/Power_For_Huge_Num/Power_Huge.java b/Mathematics/Power_For_Huge_Num/Power_Huge.java new file mode 100644 index 000000000..2b0b6da40 --- /dev/null +++ b/Mathematics/Power_For_Huge_Num/Power_Huge.java @@ -0,0 +1,82 @@ +import java.util.Scanner; +class GFG { + // Maximum number of digits in + // x^n where 1 <= x, n <= 10000 and overflow may happen + static final int MAX = 100000; + + // This function multiplies x + // with the number represented by res[]. + // res_size is size of res[] or + // number of digits in the number + // represented by res[]. This function + // uses simple school mathematics + // for multiplication. + // This function may value of res_size + // and returns the new value of res_size + static int multiply(int x, int res[], int res_size) { + + // Initialize carry + int carry = 0; + + // One by one multiply n with + // individual digits of res[] + for (int i = 0; i < res_size; i++) { + int prod = res[i] * x + carry; + + // Store last digit of + // 'prod' in res[] + res[i] = prod % 10; + + // Put rest in carry + carry = prod / 10; + } + + // Put carry in res and + // increase result size + while (carry > 0) { + res[res_size] = carry % 10; + carry = carry / 10; + res_size++; + } + return res_size; + } + + // This function finds + // power of a number x + static void power(int x, int n) { + + //printing value "1" for power = 0 + if(n == 0 ){ + System.out.print("1"); + return; + } + int res[] = new int[MAX]; + int res_size = 0; + int temp = x; + + // Initialize result + while (temp != 0) { + res[res_size++] = temp % 10; + temp = temp / 10; + } + + // Multiply x n times + // (x^n = x*x*x....n times) + for (int i = 2; i <= n; i++) + res_size = multiply(x, res, res_size); + + System.out.print(x + "^" + n + " = "); + for (int i = res_size - 1; i >= 0; i--) + System.out.print(res[i]); + } + // Driver code + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.print("Enter base: "); + int base = sc.nextInt(); + System.out.print("Enter exponent: "); + int exponent = sc.nextInt(); + power(base, exponent); + } + } + \ No newline at end of file diff --git a/Mathematics/README.md b/Mathematics/README.md new file mode 100644 index 000000000..45d922d3c --- /dev/null +++ b/Mathematics/README.md @@ -0,0 +1,9 @@ +# Armstrong Number +An Armstrong number is a number that is the sum of its own digits each raised to the power of the number of digits. + +For instance, a 3 digit number will be considered an Armstrong number if the sum of the cubes of its digits is equal to the number itself. + +``` +For example, 153 is an Armstrong number, as 1**3 + 5**3 + 3**3 = 153 +``` + diff --git a/Mathematics/Sieve of Atkin/SieveOfAtkin.js b/Mathematics/Sieve of Atkin/SieveOfAtkin.js new file mode 100644 index 000000000..ae18d8cad --- /dev/null +++ b/Mathematics/Sieve of Atkin/SieveOfAtkin.js @@ -0,0 +1,28 @@ +// In mathematics, the sieve of Atkin is a modern algorithm for finding all prime numbers up to a specified integer. + +const sieveOfAtkin = (limit = 0) => { + let primes = [2, 3]; + let sieve = new Array(limit); + for (let x = 1, xSquared = x * x; xSquared < limit; x++) { + xSquared = x * x; + for (let y = 1, ySquared = y * y; ySquared < limit; y++) { + ySquared = y * y; + let n = 4 * xSquared + ySquared; + if (n <= limit) { + let mod12Check = n % 12; + if (mod12Check === 1 || mod12Check === 5) sieve[n] = !sieve[n]; + } + let threeXSquared = 3 * xSquared; + n = threeXSquared + ySquared; + if (n <= limit && n % 12 === 7) sieve[n] = !sieve[n]; + n = threeXSquared - ySquared; + if (x > y && n <= limit && n % 12 === 11) sieve[n] = !sieve[n]; + } + } + for (let r = 5; r * r < limit; r++) + if (sieve[r]) for (let i = r * r; i < limit; i += r * r) sieve[i] = false; + for (let a = 5; a < limit; a++) if (sieve[a]) primes.push(a); + return limit < 2 ? [] : limit === 2 ? [2] : limit === 3 ? [2, 3] : primes; +}; + +export default sieveOfAtkin; diff --git a/Mathematics/Sieve of Atkin/SieveOfAtkin.test.js b/Mathematics/Sieve of Atkin/SieveOfAtkin.test.js new file mode 100644 index 000000000..69eb3f707 --- /dev/null +++ b/Mathematics/Sieve of Atkin/SieveOfAtkin.test.js @@ -0,0 +1,5 @@ +const sieveOfAtkin = require("./SieveOfAtkin.js"); + +test("Should return correct prime numbers in an array", () => { + expect(sieveOfAtkin(35)).toBe([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]); +}); diff --git a/Mathematics/Tower-of-Hanoi.md b/Mathematics/Tower-of-Hanoi.md new file mode 100644 index 000000000..94ffcbb56 --- /dev/null +++ b/Mathematics/Tower-of-Hanoi.md @@ -0,0 +1,19 @@ +# Tower of Hanoi + +The Tower of Hanoi is a mathematical game or puzzle. It consists of three rods and a number of disks of different sizes, which can slide onto any rod. The puzzle starts with the disks in a neat stack in ascending order of size on one rod, the smallest at the top, thus making a conical shape. + +The objective of the puzzle is to move the entire stack to another rod, obeying the following simple rules: + +1. Only one disk can be moved at a time. +2. Each move consists of taking the upper disk from one of the stacks and placing it on top of another stack. +3. No disk may be placed on top of a smaller disk. + +![](https://ka-perseus-images.s3.amazonaws.com/5b5fb2670c9a185b2666637461e40c805fcc9ea5.png) + +Qs: Write a program/code to solve the puzzle and calculate the minimum number of moves required to do so. + +###### For More Information: +[Wikipedia - Tower of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) + +##### Solution for 4 disks: +![](https://upload.wikimedia.org/wikipedia/commons/6/60/Tower_of_Hanoi_4.gif) diff --git a/Mathematics/cartesian_to_polar.cpp b/Mathematics/cartesian_to_polar.cpp new file mode 100644 index 000000000..703bac552 --- /dev/null +++ b/Mathematics/cartesian_to_polar.cpp @@ -0,0 +1,44 @@ +#include + +using namespace std; + +#define ll long long +#define ld long double + +#define PI 3.14159265 + +const ld to_degrees = 180.0/PI; + +struct pcord{ + ld r, theta; + + void to_pcord(ld x, ld y){ + r = sqrt(x*x+y*y); + if(x==0){ + if(y>0) theta = PI/2; + else theta = -PI/2; + } + theta = atan(abs(y/x)); + if(x>0){ + if(y>0) ; + else theta = -theta; + } + else{ + if(y>0) theta = PI - theta; + else theta = -(PI - theta); + } + } +}; + +int main(){ + ll q; + cin>>q; + while(q--){ + ll x,y; + cin>>x>>y; + pcord A; + A.to_pcord(x,y); + cout< +using namespace std; + +// Returns value of Binomial Coefficient C(n, k) +unsigned long int binomialCoeff(unsigned int n, unsigned int k) +{ + unsigned long int res = 1; + + // Since C(n, k) = C(n, n-k) + if (k > n - k) + k = n - k; + + // Calculate value of [n*(n-1)*---*(n-k+1)] / [k*(k-1)*---*1] + for (int i = 0; i < k; ++i) + { + res *= (n - i); + res /= (i + 1); + } + + return res; +} + +// A Binomial coefficient based function to find nth catalan +// number in O(n) time +unsigned long int catalan(unsigned int n) +{ + // Calculate value of 2nCn + unsigned long int c = binomialCoeff(2*n, n); + + // return 2nCn/(n+1) + return c/(n+1); +} + +// Driver program to test above functions +int main() +{ + for (int i = 0; i < 10; i++) + cout << catalan(i) << " "; + return 0; +} diff --git a/Mathematics/euclidean distance/euclidean_distance.py b/Mathematics/euclidean distance/euclidean_distance.py new file mode 100644 index 000000000..4f08f76d2 --- /dev/null +++ b/Mathematics/euclidean distance/euclidean_distance.py @@ -0,0 +1,6 @@ +import math +# Example points in 3-dimensional space... +x = (5, 6, 7) +y = (8, 9, 9) +distance = math.sqrt(sum([(a - b) ** 2 for a, b in zip(x, y)])) +print("Euclidean distance from x to y: ",distance) \ No newline at end of file diff --git a/Mathematics/factorial/C/factorial.c b/Mathematics/factorial/C/factorial.c new file mode 100644 index 000000000..fd3843bf3 --- /dev/null +++ b/Mathematics/factorial/C/factorial.c @@ -0,0 +1,17 @@ +#include + +long long factorial(int n) +{ + if (n <= 1) + { + return 1; + } + return n * factorial(n - 1); +} + +int main() +{ + int n; + scanf("%d", &n); + printf("%lld\n", factorial(n)); +} diff --git a/Mathematics/factorial/c-sharp/factorial-test.cs b/Mathematics/factorial/c-sharp/factorial-test.cs new file mode 100644 index 000000000..4dc609a0c --- /dev/null +++ b/Mathematics/factorial/c-sharp/factorial-test.cs @@ -0,0 +1,35 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace AlgorithmService.Tests +{ + [TestClass] + public class AlgorithmServiceTests + { + private readonly AlgorithmService _algorithmService; + + public BasicAlgorithmServiceTests() + { + _algorithmService = new AlgorithmService(); + } + + [TestMethod] + public void Factorialize_ReturnCorrectType() + { + var result = _algorithmService.Factorialize(5); + + Assert.IsInstanceOfType(result, typeof(long)); + } + + [DataTestMethod] + [DataRow(5, 120)] + [DataRow(10, 3628800)] + [DataRow(20, 2432902008176640000)] + [DataRow(0, 1)] + public void Factorialize_ReturnCorrectValue(int input, long expected) + { + var result = _algorithmService.Factorialize(input); + + Assert.AreEqual(expected, result); + } + } +} \ No newline at end of file diff --git a/Mathematics/factorial/c-sharp/factorial.cs b/Mathematics/factorial/c-sharp/factorial.cs new file mode 100644 index 000000000..14f72f2a7 --- /dev/null +++ b/Mathematics/factorial/c-sharp/factorial.cs @@ -0,0 +1,13 @@ +namespace Algorithms +{ + public class AlgorithmService + { + public long Factorialize(int value) + { + if (value < 0) + throw new InvalidOperationException("Please enter a value greater than or equal to zero."); + + return (value == 0) ? 1 : value * Factorialize(value - 1); + } + } +} \ No newline at end of file diff --git a/Mathematics/factorial/cpp/FactorialByDP.cpp b/Mathematics/factorial/cpp/FactorialByDP.cpp new file mode 100644 index 000000000..811e91f68 --- /dev/null +++ b/Mathematics/factorial/cpp/FactorialByDP.cpp @@ -0,0 +1,15 @@ +#include +#include + +using namespace std; + +int main() { + int n; + cin>>n; + int arr[n+1]; + arr[0]=arr[1]=1; + for(int i=2; i +using namespace std; + +#define MAX 500 + +int multiply(int x, int res[], int res_size); + +void factorial(int n) +{ + int res[MAX]; + + res[0] = 1; + int res_size = 1; + + for (int x=2; x<=n; x++) + { + res_size = multiply(x, res, res_size); + } + + cout << "Factorial of given number is \n"; + for (int i=res_size-1; i>=0; i--) + cout << res[i]; +} + +int multiply(int x, int res[], int res_size) +{ + int carry = 0; + + for (int i=0; i +using namespace std; +int main () +{ + ios_base::sync_with_stdio(false); + cin.tie(NULL); + cout.tie(NULL); + long long a,b,c; + cin >> a >> b >> c; + long long r=(b+1)%c; + for(long long i = b+2; i <=a;i++) + { + r*=i%c; + r=r%c; + if(r==0) + break; + } + cout << r; + + return 0; + +} diff --git a/Mathematics/factorial/cpp/factorial.exe b/Mathematics/factorial/cpp/factorial.exe deleted file mode 100644 index e42b61b11..000000000 Binary files a/Mathematics/factorial/cpp/factorial.exe and /dev/null differ diff --git a/Mathematics/factorial/haskell/factorial.hs b/Mathematics/factorial/haskell/factorial.hs new file mode 100644 index 000000000..e798d7cae --- /dev/null +++ b/Mathematics/factorial/haskell/factorial.hs @@ -0,0 +1,3 @@ +fat :: Int -> Int +fat 1 = 1 +fat n = fat (n -1) * n \ No newline at end of file diff --git a/Mathematics/factorial/lua/factorial.lua b/Mathematics/factorial/lua/factorial.lua new file mode 100644 index 000000000..ba80c1ba2 --- /dev/null +++ b/Mathematics/factorial/lua/factorial.lua @@ -0,0 +1,12 @@ +-- calculates the factorial of n using loop iteration +function factorial(n) + local result = 1 + + for i = 1, n do + result = result * i + end + + return result +end + +io.write(factorial(5)) diff --git a/Mathematics/factorial/python/_factorial.py b/Mathematics/factorial/python/_factorial.py new file mode 100644 index 000000000..9a25333e6 --- /dev/null +++ b/Mathematics/factorial/python/_factorial.py @@ -0,0 +1,9 @@ +def factorial(number): + fact = 1 + while number > 0: + fact *= number + number -= 1 + return fact + +n = int(input("Enter the number: ")) +print("%d! = %d" %(n, factorial(n))) diff --git a/Mathematics/factorial/python/factorial.py b/Mathematics/factorial/python/factorial.py index ff0796ae5..97c62578c 100644 --- a/Mathematics/factorial/python/factorial.py +++ b/Mathematics/factorial/python/factorial.py @@ -1,11 +1,11 @@ # Python Program to Compute the Factorial of a Number def factorial(num): - if (num < 0): + if (num < 0): #checking num is less than 0 return if (num == 1): - return 1 - return num * factorial(num - 1) + return 1 #return facyorial of 1 + return num * factorial(num - 1) #recursive call -print("5! is" + str(factorial(5))) +print("5! is" + str(factorial(5))) #calling the function print("10! is " + str(factorial(10))) diff --git a/Mathematics/fibonacci/C-Implementation.md b/Mathematics/fibonacci/C-Implementation.md new file mode 100644 index 000000000..25da34c78 --- /dev/null +++ b/Mathematics/fibonacci/C-Implementation.md @@ -0,0 +1,64 @@ +# C-Implementation of Fibonacci Prgram + +Recursive Implementation: + +```c + +#include + +int Fib(int n) +{ + // Base condition to break recursion + if (n <= 1) + return n; + + // Recursive call of function Fib for + // 'n-1'th and 'n-2'th element of sequence + return Fib(n-1) + Fib(n-2); +} + +int main() +{ + // Fibonacci sequence size + int n = 10; + + // Print the first n elements of the sequence + printf("%d", Fib(n-1)); + + return 0; +} + +``` + +Dynamic Programing Implementation: + +```c + +#include + +int main() +{ + // Fibonacci sequence size + const int n = 10; + + // Array to store the Fibonacci series + int Fib[105]; + // Initializing the first two elements of series + Fib[0] = 0; Fib[1] = 1; + + for(int i = 2; i < n; i++) + // Calculate the the 'i'th element by + // adding 'i-1'th and 'i-2'th elements + Fib[i] = Fib[i-1] + Fib[i-2]; + + // Print the first n elements of the Fibonacci sequence + for(int i = 0; i < n; i++) + { + printf("%d : %d", i, Fib[i]); + printf("\n"); + } + + return 0; +} + +``` diff --git a/Mathematics/fibonacci/C/fibonacci.c b/Mathematics/fibonacci/C/fibonacci.c new file mode 100644 index 000000000..2e972e041 --- /dev/null +++ b/Mathematics/fibonacci/C/fibonacci.c @@ -0,0 +1,40 @@ +/** + * C program to find nth Fibonacci term using recursion + */ + +#include + + +/* Function declaration */ +unsigned long long fibo(int num); + + +int main() +{ + int num; + unsigned long long fibonacci; + + /* Input a number from user */ + printf("Enter any number to find nth fiboacci term: "); + scanf("%d", &num); + + fibonacci = fibo(num); + + printf("%d fibonacci term is %llu", num, fibonacci); + + return 0; +} + + +/** + * Recursive function to find nth Fibonacci term + */ +unsigned long long fibo(int num) +{ + if(num == 0) //Base condition + return 0; + else if(num == 1) //Base condition + return 1; + else + return fibo(num-1) + fibo(num-2); +} diff --git a/Mathematics/fibonacci/Julia/fibonacci.jl b/Mathematics/fibonacci/Julia/fibonacci.jl new file mode 100644 index 000000000..df7e28194 --- /dev/null +++ b/Mathematics/fibonacci/Julia/fibonacci.jl @@ -0,0 +1,8 @@ +function fibonacci(x::Int) + if x <= 1 + return x + else + return fibonacci(x - 1) + fibonacci(x - 2) + end + return 0 +end diff --git a/Mathematics/fibonacci/Perl 6/fibonacci.p6 b/Mathematics/fibonacci/Perl 6/fibonacci.p6 new file mode 100644 index 000000000..8e4bafe44 --- /dev/null +++ b/Mathematics/fibonacci/Perl 6/fibonacci.p6 @@ -0,0 +1,10 @@ +sub fibonacci($n) { + if ($n <= 1) { return $n; } + else { + return fibonacci($n - 1) + fibonacci($n - 2); + } +} + +sub MAIN($i) { + say fibonacci($i); +} diff --git a/Mathematics/fibonacci/cpp/fibonacci.cpp b/Mathematics/fibonacci/cpp/fibonacci.cpp index f254409b6..c2f2be419 100644 --- a/Mathematics/fibonacci/cpp/fibonacci.cpp +++ b/Mathematics/fibonacci/cpp/fibonacci.cpp @@ -3,14 +3,19 @@ using namespace std; int main() { - const int n = 10; /// fibonacci sequence size - int fib[105]; - fib[1] = fib[2] = 1; - for(int i=3;i<=n;i++) - fib[i] = fib[i-1] + fib[i-2]; - for(int i=1;i<=n;i++) - cout <> n; + long a{1}, b{1}, c{}; + if(n <= 2) + cout << (n == 2? "1 1": "1"); + else{ + cout << "1 1 "; + while(i <= n){ + c = a + b; + b = a; + a = c; + cout << a << " "; + i++; + } + } } diff --git a/Mathematics/fibonacci/cpp/matrix_fibo.cpp b/Mathematics/fibonacci/cpp/matrix_fibo.cpp new file mode 100644 index 000000000..3f768c15e --- /dev/null +++ b/Mathematics/fibonacci/cpp/matrix_fibo.cpp @@ -0,0 +1,60 @@ +#include + +using namespace::std; + +int mat[2][2]; + +void power(int p) +{ +if(p<2)return; +int i,j,k; +int temp[2][2]; +temp[0][0] = mat[0][0]; +temp[0][1] = mat[0][1]; +temp[1][0] = mat[1][0]; +temp[1][1] = mat[1][1]; +int sol[2][2]; +for(i=0;i<2;++i) +for(j=0;j<2;++j) +{ +sol[i][j]=0; +for(k=0;k<2;++k) +sol[i][j]+=mat[i][k]*mat[k][j]; +} + +mat[0][0] = sol[0][0]; +mat[0][1] = sol[0][1]; +mat[1][0] = sol[1][0]; +mat[1][1] = sol[1][1]; + +power(p/2); +if(p%2==1) +{ +for(i=0;i<2;++i) +for(j=0;j<2;++j) +{ +sol[i][j]=0; +for(k=0;k<2;++k) +sol[i][j]+=mat[i][k]*temp[k][j]; +} +} + +} + +int main() +{ + +int fibo[2] = {0,1}; +mat[0][0] = 1; +mat[0][1] = 1; +mat[1][0] = 1; +mat[1][1] = 0; +int n; + +cin>>n; +power(n-1); +cout< acc1 + | n -> loop acc2 (acc1 + acc2) (n - 1I) + + loop 0I 1I n + diff --git a/Mathematics/fibonacci/haskell/fibonacci.hs b/Mathematics/fibonacci/haskell/fibonacci.hs new file mode 100644 index 000000000..1852a7c4d --- /dev/null +++ b/Mathematics/fibonacci/haskell/fibonacci.hs @@ -0,0 +1,4 @@ +fib :: Int -> Int +fib n | n == 1 = 1 + | n == 0 = 0 + | otherwise = fib(n-1) + fib(n-2) \ No newline at end of file diff --git a/Mathematics/fibonacci/lua/fibonacci.lua b/Mathematics/fibonacci/lua/fibonacci.lua new file mode 100644 index 000000000..3cd013ff9 --- /dev/null +++ b/Mathematics/fibonacci/lua/fibonacci.lua @@ -0,0 +1,13 @@ +function fibonacci(n) + if (n == 0) then + return 0 + end + + if (n == 1) then + return 1 + end + + return fibonacci(n-1) + fibonacci(n-2) +end + +io.write(fibonacci(5)) diff --git a/Mathematics/fibonacci/pascal/fibonacci.pas b/Mathematics/fibonacci/pascal/fibonacci.pas new file mode 100644 index 000000000..05583bf79 --- /dev/null +++ b/Mathematics/fibonacci/pascal/fibonacci.pas @@ -0,0 +1,22 @@ +program fibonacci; + +var + i: integer; + n: integer; + +function fib(j:integer): integer; +begin + if j = 1 then + fib := 0 + else if v = 2 then + fib := 1 + else + fib := fib(j-1) + fib(j-2); +end; + +begin + readln(n); + + for i := 1 to n do + write(fib(i), ' '); +end. diff --git a/Mathematics/fibonacci/php/fibbonacci.php b/Mathematics/fibonacci/php/fibbonacci.php new file mode 100644 index 000000000..2ef77ca1f --- /dev/null +++ b/Mathematics/fibonacci/php/fibbonacci.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/Mathematics/fibonacci/python/fibo.py b/Mathematics/fibonacci/python/fibo.py index bf9f4d28b..18de432b9 100644 --- a/Mathematics/fibonacci/python/fibo.py +++ b/Mathematics/fibonacci/python/fibo.py @@ -3,11 +3,3 @@ def recur_fibo(n): return n else: return(recur_fibo(n-1) + recur_fibo(n-2)) -nterms = int(input("How many terms? ")) - -if nterms <= 0: - print("Plese enter a positive integer") -else: - print("Fibonacci sequence:") - for i in range(nterms): - print(recur_fibo(i)) diff --git a/Mathematics/findmax.py b/Mathematics/findmax.py new file mode 100644 index 000000000..d16a9dc1f --- /dev/null +++ b/Mathematics/findmax.py @@ -0,0 +1,10 @@ +# NguyenU + +import math + +def find_max(nums): + max = 0 + for x in nums: + if x > max: + max = x + print max diff --git a/Mathematics/harmonic mean/C/Makefile b/Mathematics/harmonic mean/C/Makefile new file mode 100644 index 000000000..dfd4164d5 --- /dev/null +++ b/Mathematics/harmonic mean/C/Makefile @@ -0,0 +1,5 @@ +CC=gcc +CFLAGS=-I. + +harmonicMean: + $(CC) harmonicMean.c -o harmonicMean diff --git a/Mathematics/harmonic mean/C/harmonicMean.c b/Mathematics/harmonic mean/C/harmonicMean.c new file mode 100644 index 000000000..ce77b1bab --- /dev/null +++ b/Mathematics/harmonic mean/C/harmonicMean.c @@ -0,0 +1,11 @@ +#include + +double harmonicMean(int firstNum, int secondNum){ + return ((double)2*firstNum*secondNum / (double)(firstNum + secondNum)); +} + +int main(int argc, char const *argv[]) { + double result=harmonicMean(31,69); + printf("Harmonic mean of %d and %d is:%lf\n",31,69, result); + return 0; +} diff --git a/Mathematics/juggler sequence/C/juggler_seq.c b/Mathematics/juggler sequence/C/juggler_seq.c new file mode 100644 index 000000000..b2c92d646 --- /dev/null +++ b/Mathematics/juggler sequence/C/juggler_seq.c @@ -0,0 +1,43 @@ +// C implementation of Juggler Sequence +#include +#include + +// This function prints the juggler Sequence +void printJuggler(int n) +{ + int a = n; + + // print the first term + printf("%d ", a); + + // calculate terms until last term is not 1 + while (a != 1) + { + int b = 0; + + // Check if previous term is even or odd + if (a%2 == 0) + + // calculate next term + b = floor(sqrt(a)); + + else + + // for odd previous term calculate + // next term + b = floor(sqrt(a)*sqrt(a)*sqrt(a)); + + printf("%d ", b); + a = b; + } +} + +//driver program to test above function +int main() +{ + int n; + printf("Enter any Integer\n"); + scanf("%d",&n); + printJuggler(n); + return 0; +} diff --git a/Mathematics/log 2 n/log2n.java b/Mathematics/log 2 n/log2n.java new file mode 100644 index 000000000..394d958e9 --- /dev/null +++ b/Mathematics/log 2 n/log2n.java @@ -0,0 +1,16 @@ +import java.util.*; +import java.lang.*; +import java.io.*; +class log2n +{ + public static double log2(int n) + { + return Math.log(n) / Math.log(2); + } + public static void main (String[] args) throws Exception + { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + System.out.println(log2(n)); + } +} diff --git a/Mathematics/modular exp/cpp/modular_exp.cpp b/Mathematics/modular exp/cpp/modular_exp.cpp new file mode 100644 index 000000000..0dd034dda --- /dev/null +++ b/Mathematics/modular exp/cpp/modular_exp.cpp @@ -0,0 +1,28 @@ +#include +using namespace std; + +/// modn is the chosen prime +const long long modn = 1000000007; +inline long long mod(long long x) { return x % modn; } + +long long expo(long long num, long long exp){ + long long ans = 1; + while(exp){ + if(exp&1) + ans = mod(ans*num); + num = mod(num*num); + exp >>= 1; + } + return ans; +} + +// computes x's modular inverse +long long mod_inv(long long x){ + return expo(x, modn-2); +} + +int main (){ + long long x, exp; + scanf("%lld %lld", &x, &exp); + printf("%lld\n", expo(x, exp)); +} diff --git a/Mathematics/modular exp/java/ModularExp.java b/Mathematics/modular exp/java/ModularExp.java new file mode 100644 index 000000000..f50431ba7 --- /dev/null +++ b/Mathematics/modular exp/java/ModularExp.java @@ -0,0 +1,25 @@ +public class ModularExp { + // computes n raised to the nonnegative power e modulo m + public static long exp(long n, int e, int m) { + if (e == 0) { + return 1L; + } + + n %= m; + long ans = 1; + + if (e%2 == 0) { + return exp(ans*ans, e/2, m); + } + else { + return n*exp(ans*ans, e/2, m); + } + } + + public static void main(String[] args) { + long n = 137; + int e = 207; + int m = 18; + System.out.println(exp(n,e,m)); + } +} diff --git a/Mathematics/modular exp/python/ModularExp.py b/Mathematics/modular exp/python/ModularExp.py index a9b7772f6..36a0d0ced 100644 --- a/Mathematics/modular exp/python/ModularExp.py +++ b/Mathematics/modular exp/python/ModularExp.py @@ -1,14 +1,18 @@ #! python 3 -def power(x, y ,p ) : + +# base, exponent, and prime (mod) +x = 2 +y = 32 +p = 1023 + +def power(x, y, p): res = 1 x = x%p - while(y>0) : - if y %2 == 1 : - res = (res*x) % p + while y>0: + if y%2 == 1: + res = (res*x)%p y = y/2 x = (x*x)%p return res - - -print( power(2,32,1023)) +print(power(x,y,p)) diff --git a/Mathematics/modularInverse/go/src/main.go b/Mathematics/modularInverse/go/src/main.go new file mode 100644 index 000000000..82a28fd15 --- /dev/null +++ b/Mathematics/modularInverse/go/src/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "errors" + "fmt" +) + +func egcd(a int, b int) (int, int, int) { + if a == 0 { + return b, 0, 1 + } else { + g, y, x := egcd(b%a, a) + r := x - (b/a)*y + return g, r, y + } +} + +func modInv(a int, m int) (int, error) { + g, x, _ := egcd(a, m) + if g != 1 { + return 0, errors.New("modular inverse does not exist") + } else { + return x % m, nil + } +} + +func main() { + a := 0 + m := 0 + fmt.Println("Find Modular Inverse") + fmt.Println("Enter a") + fmt.Scanln(&a) + fmt.Println("Enter m") + fmt.Scanln(&m) + + result, err := modInv(a, m) + if err != nil { + fmt.Printf("Modular of %v with modular %v does not exist", a, m) + } + fmt.Printf("Modular of %v with modular %v is %v", a, m, result) +} diff --git a/Mathematics/palindrome/JavaScript/palindrome.js b/Mathematics/palindrome/JavaScript/palindrome.js new file mode 100644 index 000000000..c367b5c35 --- /dev/null +++ b/Mathematics/palindrome/JavaScript/palindrome.js @@ -0,0 +1,26 @@ +function palindrome(str) { + str = str.toLowerCase(); + str = str.replace(/[\s_,.()|:-]/g, ""); + + let newStr = str.split("").reverse().join(""); + if(newStr === str){ + output = true; + } + else{ + output = false; + } + console.log(output); +} + +palindrome("eye"); +palindrome("_eye"); +palindrome("race car"); +palindrome("not a palindrome"); +palindrome("A man, a plan, a canal. Panama"); +palindrome("never odd or even"); +palindrome("nope"); +palindrome("almostomla"); +palindrome("My age is 0, 0 si ega ym."); +palindrome("1 eye for of 1 eye.") +palindrome("0_0 (: /-\ :) 0-0"); +palindrome("five|\_/|four"); \ No newline at end of file diff --git a/Mathematics/palindrome/c/palindrome b/Mathematics/palindrome/c/palindrome new file mode 100755 index 000000000..fa4a47454 Binary files /dev/null and b/Mathematics/palindrome/c/palindrome differ diff --git a/Mathematics/palindrome/c/palindrome.c b/Mathematics/palindrome/c/palindrome.c new file mode 100644 index 000000000..23d35b481 --- /dev/null +++ b/Mathematics/palindrome/c/palindrome.c @@ -0,0 +1,25 @@ +#include + +int reverse(int x){ + int reverse = 0; + while (x){ + reverse = reverse * 10 + (x % 10); + x /= 10; + } + return reverse; +} + +void palindrome(int x){ + if (x == reverse(x)) + printf("This number is a palindrome !\n"); + else + printf("This number is not a palindrome !\n"); +} + +int main() { + int x; + scanf("%d", &x); + palindrome(x); + return 0; +} + diff --git a/Mathematics/palindrome/haskell/Main.hs b/Mathematics/palindrome/haskell/Main.hs new file mode 100644 index 000000000..121cec747 --- /dev/null +++ b/Mathematics/palindrome/haskell/Main.hs @@ -0,0 +1,12 @@ +module Main where + +import Palindrome + +main :: IO() +main = do + print $ ispalindrome 100 + print $ ispalindrome 101 + + print $ ispalindromeStrings "woop" + print $ ispalindromeStrings "woopoow" + diff --git a/Mathematics/palindrome/haskell/Palindrome.hs b/Mathematics/palindrome/haskell/Palindrome.hs new file mode 100644 index 000000000..30a440240 --- /dev/null +++ b/Mathematics/palindrome/haskell/Palindrome.hs @@ -0,0 +1,7 @@ +module Palindrome where + +ispalindrome :: Int -> Bool +ispalindrome a = a == (read ( reverse $ show a ) ::Int) + +ispalindromeStrings :: String -> Bool +ispalindromeStrings a = a == (reverse a) \ No newline at end of file diff --git a/Mathematics/palindrome/java/palindrome.class b/Mathematics/palindrome/java/palindrome.class new file mode 100644 index 000000000..ffe18b94d Binary files /dev/null and b/Mathematics/palindrome/java/palindrome.class differ diff --git a/Mathematics/palindrome/java/palindrome.java b/Mathematics/palindrome/java/palindrome.java new file mode 100644 index 000000000..2750d2c31 --- /dev/null +++ b/Mathematics/palindrome/java/palindrome.java @@ -0,0 +1,26 @@ +import java.util.*; +import java.io.*; + +public class palindrome { + public static void main(String args[]) { + int num,d,r,n; + Scanner s = new Scanner(System.in); + r=0; + System.out.println("Enter a number: "); + num = s.nextInt(); + n = num; + do { + d = num%10; + r = (r*10) + d; + num = num/10; + } while(num!=0); + + System.out.println(n+" "+r); + + if(n==r) + System.out.println("It is a palindrome"); + else + System.out.println("It is not a palindrome"); + + } +} diff --git a/Mathematics/palindrome/palindrome-number.cpp b/Mathematics/palindrome/palindrome-number.cpp new file mode 100644 index 000000000..12ab25fc9 --- /dev/null +++ b/Mathematics/palindrome/palindrome-number.cpp @@ -0,0 +1,28 @@ +#include +using namespace std; + +int main() +{ + int n,num,digit,rev = 0; + + cout<<"Enter a positive number: "; + cin>>num; + + n = num; + + do + { + digit = num % 10; + rev = (rev * 10) + digit; + num = num / 10; + } while (num != 0); + + cout<<"The reverse of the number is: "< + +int main() +{ + int n, num, rev = 0; + + /* Input a number from user */ + printf("Enter any number to check palindrome: "); + scanf("%d", &n); + + /* Copy original value to 'num' to 'n'*/ + num = n; + + /* Find reverse of n and store in rev */ + while(n != 0) + { + rev = (rev * 10) + (n % 10); + n /= 10; + } + + /* Check if reverse is equal to 'num' or not */ + if(rev == num) + { + printf("%d is palindrome.", num); + } + else + { + printf("%d is not palindrome.", num); + } + + return 0; +} diff --git a/Mathematics/palindrome/python/number_palindrome.py b/Mathematics/palindrome/python/number_palindrome.py new file mode 100644 index 000000000..3a0e090c2 --- /dev/null +++ b/Mathematics/palindrome/python/number_palindrome.py @@ -0,0 +1,13 @@ +num = int(input("Enter a number: ")) + +temp = num +rev = 0 + +while temp != 0: + rev = (rev * 10) + (temp % 10) + temp = temp // 10 + +if num == rev: + print("number is palindrome") +else: + print("number is not palindrome") \ No newline at end of file diff --git a/Mathematics/prime factors/C/prime_factor.c b/Mathematics/prime factors/C/prime_factor.c new file mode 100644 index 000000000..98fa6609c --- /dev/null +++ b/Mathematics/prime factors/C/prime_factor.c @@ -0,0 +1,43 @@ +/** + * C program to find all prime factors of a given number + */ + +#include + +int main() +{ + int i, j, num, isPrime; + + /* Input a number from user */ + printf("Enter any number to print Prime factors: "); + scanf("%d", &num); + + printf("All Prime Factors of %d are: \n", num); + + /* Find all Prime factors */ + for(i=2; i<=num; i++) + { + /* Check 'i' for factor of num */ + if(num%i==0) + { + /* Check 'i' for Prime */ + isPrime = 1; + for(j=2; j<=i/2; j++) + { + if(i%j==0) + { + isPrime = 0; + break; + } + } + + /* If 'i' is Prime number and factor of num */ + if(isPrime==1) + { + printf("%d, ", i); + } + } + } + + return 0; +} diff --git a/Mathematics/prime factors/go/primefactorization.go b/Mathematics/prime factors/go/primefactorization.go new file mode 100644 index 000000000..facc1c24b --- /dev/null +++ b/Mathematics/prime factors/go/primefactorization.go @@ -0,0 +1,22 @@ +package primefactorization + +func primeFactors(n uint64) []uint64 { + primes := make([]uint64, 0); + + if n == 1 { + return primes + } + + tmp := uint64(2) + for tmp <= n { + if n % tmp == 0 { + primes = append(primes, tmp) + n = n/tmp + tmp = uint64(1) + } + tmp++ + } + + return primes +} + diff --git a/Mathematics/prime factors/go/primefactorization_test.go b/Mathematics/prime factors/go/primefactorization_test.go new file mode 100644 index 000000000..fc4830a23 --- /dev/null +++ b/Mathematics/prime factors/go/primefactorization_test.go @@ -0,0 +1,16 @@ +package primefactorization + +import ( + _ "testing" + "testing" +) + +func Test(t *testing.T) { + primes := primeFactors(91) + if primes[0] != uint64(7) { + t.Error("first factor is not 7") + } + if primes[1] != uint64(13) { + t.Error("second factor is not 13") + } +} diff --git a/Mathematics/prime factors/java/PrimeFactorTest.java b/Mathematics/prime factors/java/PrimeFactorTest.java new file mode 100644 index 000000000..e3a834088 --- /dev/null +++ b/Mathematics/prime factors/java/PrimeFactorTest.java @@ -0,0 +1,18 @@ +import java.util.ArrayList; +import org.junit.Test; + + +/** + * Testing prime factorization + * @author Magro28 + */ +public class PrimeFactorTest { + + @Test + public void test() { + + ArrayList primefactorize = PrimeFactorization.primefactorize(91); + assert(primefactorize.contains(7l)); + assert(primefactorize.contains(13l)); + } +} diff --git a/Mathematics/prime factors/java/PrimeFactorization.java b/Mathematics/prime factors/java/PrimeFactorization.java new file mode 100644 index 000000000..e69de29bb diff --git a/Mathematics/prime factors/javascript/prime_factors.js b/Mathematics/prime factors/javascript/prime_factors.js new file mode 100644 index 000000000..dbd9722c8 --- /dev/null +++ b/Mathematics/prime factors/javascript/prime_factors.js @@ -0,0 +1,28 @@ +/* + * Function that returns a list of all prime factors of a number + */ +function prime_factors(n) { + let factors = [] + while (n % 2 == 0) { + factors.push(2); + n = n / 2; + } + for (let k = 3; k < Math.floor(Math.sqrt(n)) + 1; k = k + 2){ + while (n % k == 0) { + factors.push(k); + n = n / k; + } + } + if ( n > 2){ + factors.push(n); + } + return factors; +} + + +/* + * Tests + */ + +let n = 315; +console.log(prime_factors(n)); diff --git a/Mathematics/prime.cpp b/Mathematics/prime.cpp new file mode 100644 index 000000000..af26ed3b5 --- /dev/null +++ b/Mathematics/prime.cpp @@ -0,0 +1,46 @@ +// Implementation of prime factorisation of big integers using Pollard-Rho algorithm in cpp + +// Author: Saloni Rajeev Kumar +// Date: 19 October + +#include +using namespace std; +typedef long long int ll; + +ll modular_pow(ll base, int exponent, ll modulus) { + ll result = 1; + while (exponent > 0) { + if (exponent & 1) + result = (result * base) % modulus; + exponent = exponent >> 1; + base = (base * base) % modulus; + } + return result; +} + +ll PollardRho(ll n) { + srand (time(NULL)); + if (n==1) return n; + if (n % 2 == 0) return 2; + ll x = (rand()%(n-2))+2; + ll y = x; + ll c = (rand()%(n-1))+1; + ll d = 1; + + while (d==1) { + x = (modular_pow(x, 2, n) + c + n)%n; + y = (modular_pow(y, 2, n) + c + n)%n; + y = (modular_pow(y, 2, n) + c + n)%n; + d = __gcd(abs(x-y), n); + if (d==n) return PollardRho(n); + } + return d; +} + +int main() { + ll n; + scanf("%lld", &n); + printf("One of the divisors for %lld is %lld.", + n, PollardRho(n)); + return 0; +} diff --git a/Mathematics/primePyramid b/Mathematics/primePyramid new file mode 100644 index 000000000..907ed8880 --- /dev/null +++ b/Mathematics/primePyramid @@ -0,0 +1,35 @@ +#include + +int prime(int num); +int main() { + int i, j; + int num = 2; + + for (i = 0; i < 5; i++) { + printf("\n"); + for (j = 0; j <= i; j++) { + while (!prime(num)) { + num++; + } + printf("%d\t", num++); + } + } + return (0); +} + +int prime(int num) { + int i, flag; + for (i = 2; i < num; i++) { + if (num % i != 0) + flag = 1; + else { + flag = 0; + break; + } + } + + if (flag == 1 || num == 2) + return (1); + else + return (0); +} diff --git a/Mathematics/prime_numbers.py b/Mathematics/prime_numbers.py new file mode 100644 index 000000000..207dee90e --- /dev/null +++ b/Mathematics/prime_numbers.py @@ -0,0 +1,20 @@ + + +print("Type a number") +n = input() +a = 2 +b = True + + +while a < int(n): + if int(n) % a == 0 : + print("n is not a prime number!") + a = int(n) + b = False + + a = a + 1 + + + +if b == True: + print("n is a prime number!") diff --git a/Mathematics/reverse number/Java/ReverseNumber.java b/Mathematics/reverse number/Java/ReverseNumber.java new file mode 100644 index 000000000..77b08aa37 --- /dev/null +++ b/Mathematics/reverse number/Java/ReverseNumber.java @@ -0,0 +1,12 @@ +public class ReverseNumber { + public static void main(String[] args) { + int num = 1234, reversed = 0; + while(num != 0) { + int digit = num % 10; + reversed = reversed * 10 + digit; + num /= 10; + } + + System.out.println("Reversed Number: " + reversed); + } +} diff --git a/Mathematics/reverse number/reverse-no.c b/Mathematics/reverse number/reverse-no.c new file mode 100644 index 000000000..436b1a78e --- /dev/null +++ b/Mathematics/reverse number/reverse-no.c @@ -0,0 +1,15 @@ +#include +void main() +{ + int num,rev=0,i,temp; + printf("Enter the number you want to reverse\n"); + scanf("%d",&num); + temp=num; + while(num!=0) + { + i=num%10; + rev=(rev*10)+i; + num=num/10; + } + printf("Reverse of the number %d is %d",temp,rev); +} diff --git a/Mathematics/reverse number/reverse.c b/Mathematics/reverse number/reverse.c new file mode 100644 index 000000000..3d83a21f1 --- /dev/null +++ b/Mathematics/reverse number/reverse.c @@ -0,0 +1,17 @@ +#include + +int reverse(int x){ + int reverse = 0; + while (x) { + reverse = reverse * 10 + (x % 10); + x /= 10; + } + return reverse; +} + +int main(){ + int x; + scanf("%d", &x); + printf("%d\n", reverse(x)); + return 0; +} diff --git a/Mathematics/reverse number/reverseNumber.js b/Mathematics/reverse number/reverseNumber.js new file mode 100644 index 000000000..3cd4e09f0 --- /dev/null +++ b/Mathematics/reverse number/reverseNumber.js @@ -0,0 +1,17 @@ +function revInt(num) { + var rem, rev=0; + while(num > 0){ + rem = num % 10; + rev = rev*10 + rem; + num = parseInt(num/10); + } + console.log(rev); +} + +// Commented Out ShortCut method +// const revInt = (n) => { +// let rev = n.toString().split('').reverse().join(""); +// console.log(Number(rev)); +// } + +revInt(15); \ No newline at end of file diff --git a/Mathematics/sieve of Eratosthenes/cpp/Sieve of Eratosthenes.js b/Mathematics/sieve of Eratosthenes/Javascript/Sieve of Eratosthenes.js similarity index 96% rename from Mathematics/sieve of Eratosthenes/cpp/Sieve of Eratosthenes.js rename to Mathematics/sieve of Eratosthenes/Javascript/Sieve of Eratosthenes.js index 44f503d63..2e87a1f0b 100644 --- a/Mathematics/sieve of Eratosthenes/cpp/Sieve of Eratosthenes.js +++ b/Mathematics/sieve of Eratosthenes/Javascript/Sieve of Eratosthenes.js @@ -21,4 +21,4 @@ const sieve = max => { return primes }, []) -} \ No newline at end of file +} diff --git a/Mathematics/trailing_zeros_in_factorial/trailing_zeros.c b/Mathematics/trailing_zeros_in_factorial/trailing_zeros.c new file mode 100644 index 000000000..1d9a7b14b --- /dev/null +++ b/Mathematics/trailing_zeros_in_factorial/trailing_zeros.c @@ -0,0 +1,19 @@ +#include + +int main() { + int x, zeros = 0; + + scanf("%d", &x); + for (int i = 1; i <= x; ++i) { + int aux = i; + + while (aux % 5 == 0) { + aux = aux / 5; + zeros++; + } + } + + printf("%d\n", zeros); + + return 0; +} \ No newline at end of file diff --git a/Mathematics/trailing_zeros_in_factorial/trailing_zeros.py b/Mathematics/trailing_zeros_in_factorial/trailing_zeros.py new file mode 100644 index 000000000..a27c724b9 --- /dev/null +++ b/Mathematics/trailing_zeros_in_factorial/trailing_zeros.py @@ -0,0 +1,14 @@ +def main(): + zeros = 0 + power_of_five = 5 + x = int(input("Number: ")) + + while power_of_five < x: + zeros += x // power_of_five + power_of_five *= 5 + print("Number of zeros: " + str(zeros)) + + +if __name__ == '__main__': + main() + diff --git a/Numerical Methods/secant_method/C/bisection.c b/Numerical Methods/secant_method/C/bisection.c new file mode 100644 index 000000000..56112ea75 --- /dev/null +++ b/Numerical Methods/secant_method/C/bisection.c @@ -0,0 +1,44 @@ +#include +#include + +//#define ESP 0.001 +//#define F(x) (x)*(x)*(x) + (x)*(x) + (x) + 7 +double F(float x) +{ +return ((x*x*x)-x-1); + +} +void main() +{ + int i = 1; + float x0,x1,x2; + double f1,f2,f0,t; + + printf("\nEnter the value of x0: "); + scanf("%f",&x0); + + printf("\nEnter the value of x1: "); + scanf("%f",&x1); + + printf("\niteration\t x0\t x1\t x2\t f0\t f1\t f2"); + do{ + + x2=(x0+x1)/2; + /* f0=F(x0); + f1=F(x1); + f2=F(x2);*/ + printf("\n%d %f %f %f %lf %lf %lf", i, x0,x1,x2,F(x0),F(x1),F(x2)); + if(F(x0)*F(x2)<0) + { + x1=x2; + } + else + { + x0=x2; + } + i++; + }while(fabs(F(x2))>0.001); + +printf("\n\nApp.root = %f",x2); + +} diff --git a/Numerical Methods/secant_method/C/gaussseidel.c b/Numerical Methods/secant_method/C/gaussseidel.c new file mode 100644 index 000000000..09e835613 --- /dev/null +++ b/Numerical Methods/secant_method/C/gaussseidel.c @@ -0,0 +1,42 @@ +#include +//#include +#include +#define ESP 0.0001 +#define X1(x2,x3) ((17 - 20*(x2) + 2*(x3))/20) +#define X2(x1,x3) ((-18 - 3*(x1) + (x3))/20) +#define X3(x1,x2) ((25 - 2*(x1) + 3*(x2))/20) + + +void main() +{ + double x1=0,x2=0,x3=0,y1,y2,y3; + int i=0; + //clrscr(); + // printf("\n__________________________________________\n"); + printf("\n x1\t\t x2\t\t x3\n"); + //printf("\n__________________________________________\n"); + printf("\n%f\t%f\t%f",x1,x2,x3); + do + { + y1=X1(x2,x3); + y2=X2(y1,x3); + y3=X3(y1,y2); + if(fabs(y1-x1) +#include +#include +#define ESP 0.0001 +#define X1(x2,x3) ((17 - 20*(x2) + 2*(x3))/20) +#define X2(x1,x3) ((-18 - 3*(x1) + (x3))/20) +#define X3(x1,x2) ((25 - 2*(x1) + 3*(x2))/20) + + +void main() +{ + double x1=0,x2=0,x3=0,y1,y2,y3; + int i=0; + clrscr(); + printf("\n__________________________________________\n"); + printf("\n x1\t\t x2\t\t x3\n"); + printf("\n__________________________________________\n"); + printf("\n%f\t%f\t%f",x1,x2,x3); + do + { + y1=X1(x2,x3); + y2=X2(x1,x3); + y3=X3(x1,x2); + if(fabs(y1-x1) +#include +#define MaxN 90 + +void main() +{ + float arr_x[MaxN+1], arr_y[MaxN+1], numerator, denominator, x, y=0; + int i, j, n; + clrscr(); + printf("Enter the value of n: \n"); + scanf("%d", &n); + printf("Enter the values of x and y: \n"); + for(i=0; i<=n; i++) + scanf("%f%f", &arr_x[i], &arr_y[i]); + printf("Enter the value of x at which value of y is to be calculated: "); + scanf("%f", &x); + for (i=0; i<=n; i++) + { + numerator=1; + denominator=1; + for (j=0; j<=n; j++) + if(j!=i) + { + numerator *= x-arr_x[j]; + denominator *= arr_x[i]-arr_x[j]; + } + y+=(numerator/denominator)*arr_y[i]; + } + printf("When x=%4.1f y=%7.1f\n",x,y); + getch(); +} \ No newline at end of file diff --git a/Numerical Methods/secant_method/Java/Secant Method.java b/Numerical Methods/secant_method/Java/Secant Method.java new file mode 100644 index 000000000..45f5deab1 --- /dev/null +++ b/Numerical Methods/secant_method/Java/Secant Method.java @@ -0,0 +1,72 @@ + Java Program to find root of an + equations using secant method +class GFG { + + function takes value of x and + returns f(x) + static float f(float x) { + + we are taking equation + as x^3+x-1 + float f = (float)Math.pow(x, 3) + + x - 1; + + return f; + } + + static void secant(float x1, float x2, + float E) { + + float n = 0, xm, x0, c; + if (f(x1) f(x2) 0) + { + do { + + calculate the intermediate + value + x0 = (x1 f(x2) - x2 f(x1)) + (f(x2) - f(x1)); + + check if x0 is root of + equation or not + c = f(x1) f(x0); + + update the value of interval + x1 = x2; + x2 = x0; + + update number of iteration + n++; + + if x0 is the root of equation + then break the loop + if (c == 0) + break; + xm = (x1 f(x2) - x2 f(x1)) + (f(x2) - f(x1)); + + repeat the loop until the + convergence + } while (Math.abs(xm - x0) = E); + + System.out.println(Root of the + + given equation= + x0); + + System.out.println(No. of + + iterations = + n); + } + + else + System.out.print(Can not find a + + root in the given inteval); + } + + Driver code + public static void main(String[] args) { + + initializing the values + float x1 = 0, x2 = 1, E = 0.0001f; + secant(x1, x2, E); + } +} + \ No newline at end of file diff --git a/Numerical Methods/secant_method/python/function.py b/Numerical Methods/secant_method/python/function.py new file mode 100644 index 000000000..655747571 --- /dev/null +++ b/Numerical Methods/secant_method/python/function.py @@ -0,0 +1,13 @@ +import math +import numpy as np + +def funct(x): +# y = math.exp(x) +# y = y - x + +# y = np.sin(x) + + + y = np.pi*(x**2)*3 - ((np.pi)*(x**3))/3 - 30 + + return y diff --git a/Numerical Methods/secant_method/python/main.py b/Numerical Methods/secant_method/python/main.py new file mode 100644 index 000000000..8d1c5f6ae --- /dev/null +++ b/Numerical Methods/secant_method/python/main.py @@ -0,0 +1,20 @@ +from secant_method import SecantMethod +from function import funct + +# SECANT METHOD: + +# INPUT: +# A FUNCTION THAT TAKES ONE PARAMETER AND RETURNS A VALUE +# A VALUE FOR X2 +# A VALUE FOR X1 +# AN ERROR ESTIMATION +# THE MAX NUMBER OF STEPS + + +# OUTPUT: +# THE ROOT FOR THE DESIRED FUNTION +# . + +method = SecantMethod(funct,0,3,.00001,30) +x = method.secant_method() +print(x) diff --git a/Numerical Methods/secant_method/python/secant_method.py b/Numerical Methods/secant_method/python/secant_method.py new file mode 100644 index 000000000..babf9065d --- /dev/null +++ b/Numerical Methods/secant_method/python/secant_method.py @@ -0,0 +1,56 @@ +class SecantMethod: + + def __init__(self, function_, initial_guess_1, initial_guess_2, tol, max_steps): + self.function = function_ + self.x_2 = initial_guess_1 + self.x_1 = initial_guess_2 + self.tolerance = tol + self.maxSteps = max_steps + + def secant_method(self): + + + #VARIABLES INITIALIZE GUESSES FOR X1 AND X2 + x1=self.x_1 + x2=self.x_2 + + #EVALUATE X1 AT F(X1) + fx1=self.function(x1) + + #INITIALIZE DELTA VARIABLE FOR LATER USE. THIS VARIABLE WILL REFER TO THE FUNCTION DELTA_X + deltax = 0 + + #ITERATE OVER DATA UNTIL VALUE CONVERGES + for i in range(self.maxSteps): + + #EVALUATE X2 AT F(X2) + fx2 = self.function(x2) + + #EVALUATE DELTA_X + deltax = self.delta_x(fx2,fx1,x2,x1) + + #PRINT ON TERMINAL APPROXIMATED VALUE + print("root_apprx= ",x2) + + #EXCHANGE POINT POSITIONS. + #MAKE X2 EQUAL TO X1 + #MAKE F(X2) EQUAL F(X1) + #MAKE X2 EQUAL TO X2 - DELTAX + x1 = x2 + fx1 = fx2 + x2 = x2-deltax + + #IF THE ABSOLUTE VALUE OF DELTA_X IS LESS THAN THE TOLERANCE + #VALUE HAS BEEN FOUND + if(abs(deltax) < self.tolerance): + return x2 + + + # calculates (f2/f2-1)(x2-x1) + def delta_x(self,f2,f1,x2,x1): + #WATCH FOR DIVISION BY ZERO + if((f2-f1)*(x2-x1) == 0): + print("Division by zero") + exit(0) + else: + return(f2/(f2-f1))*(x2-x1) diff --git a/Optimization/GradientDescent.py b/Optimization/GradientDescent.py new file mode 100644 index 000000000..2385b9580 --- /dev/null +++ b/Optimization/GradientDescent.py @@ -0,0 +1,21 @@ +def GradientDescent(inputValue, learningRate, precision, maximumIterations, gradientFunction): + previousStepSize = 1 + iterationCounter = 0 + while previousStepSize > precision and iterationCounter < maximumIterations: + previousX = inputValue #Storing current x value in previousX + inputValue = inputValue - learningRate * gradientFunction(previousX) #Grad descent + previousStepSize = abs(inputValue - previousX) #Change in x + iterationCounter = iterationCounter+1 #iteration count + print("Iteration",iterationCounter,"\nX value is",inputValue) #Print iterations + return inputValue + +inputValue = float(input("Initial Value: ")) +learningRate = float(input("Learning Rate Alpha: ")) +precision = float(input("Precision Needed: ")) +maximumIterations = float(input("Maximum Iterations: ")) +print(float(input("Trial Number: "))) +gradientFunction = lambda x: 2*(x+5) #Gradient of our function + +minimum = GradientDescent(inputValue, learningRate, precision, maximumIterations, gradientFunction) + +print("The local minimum value is", minimum) \ No newline at end of file diff --git a/Other Algorithms/AStar/astar.py b/Other Algorithms/AStar/astar.py new file mode 100644 index 000000000..a4feaf290 --- /dev/null +++ b/Other Algorithms/AStar/astar.py @@ -0,0 +1,115 @@ +#Class Definition of Node +class Node(): + def __init__(self, parent=None, position=None): + self.parent = parent + self.position = position + + self.g = 0 + self.h = 0 + self.f = 0 + + def __eq__(self, other): + return self.position == other.position + +#return the path from start to end +def astar(maze, start, end): + + startNode = Node(None, start) + startNode.g = startNode.h = startNode.f = 0 + endNode = Node(None, end) + endNode.g = endNode.h = endNode.f = 0 + + # Initialize both open and closed list + openList = [] + closedList = [] + + # Add the start node + openList.append(startNode) + + # Loop until you find the end + while len(openList) > 0: + + # Get the current node + currentNode = openList[0] + currentIndex = 0 + for index, item in enumerate(openList): + if item.f < currentNode.f: + currentNode = item + currentIndex = index + + # Pop current off open list, add to closed list + openList.pop(currentIndex) + closedList.append(currentNode) + + # Goal Found + if currentNode == endNode: + path = [] + current = currentNode + while current is not None: + path.append(current.position) + current = current.parent + return path[::-1] # Return reversed path + + # Generating children + children = [] + for newPosition in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares + + # current Node position + nodePosition = (currentNode.position[0] + newPosition[0], currentNode.position[1] + newPosition[1]) + + ##In range + if nodePosition[0] > (len(maze) - 1) or nodePosition[0] < 0 or nodePosition[1] > (len(maze[len(maze)-1]) -1) or nodePosition[1] < 0: + continue + + # Make sure walkable path + if maze[nodePosition[0]][nodePosition[1]] != 0: + continue + + newNode = Node(currentNode, nodePosition) + + children.append(newNode) + + # Loop through children + for child in children: + + # Child is on the closed list + for closedChild in closedList: + if child == closedChild: + continue + + # Create the f, g, and h values + child.g = currentNode.g + 1 + child.h = ((child.position[0] - endNode.position[0]) ** 2) + ((child.position[1] - endNode.position[1]) ** 2) + child.f = child.g + child.h + + # Child is already in the open list + for openNode in openList: + if child == openNode and child.g > openNode.g: + continue + + # Add the child to the open list + openList.append(child) + + +def main(): + + maze = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] + + start = (0, 0) + end = (7, 6) + + path = astar(maze, start, end) + print(path) + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/Other Algorithms/All_permutations_of_a_string.cpp b/Other Algorithms/All_permutations_of_a_string.cpp new file mode 100644 index 000000000..0cd6e59f2 --- /dev/null +++ b/Other Algorithms/All_permutations_of_a_string.cpp @@ -0,0 +1,48 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: main.cpp + * Author: Elkay + * + * Created on 17 October, 2018, 10:26 PM + */ + +#include + +using namespace std; + +void swap(char *x, char *y){ + char temp; + temp = *x; + *x = *y; + *y = temp; +} +void permute(char *a, int l, int r){ + int i; + if(l == r){ + cout<>s; + int n = s.length(); + + char str[n+1]; + strcpy(str,s.c_str()); + permute(str,0,n-1); + return 0; +} + diff --git a/Other Algorithms/Check Wagstaff Prime/Wagstaff.cpp b/Other Algorithms/Check Wagstaff Prime/Wagstaff.cpp new file mode 100644 index 000000000..7cc88b9b1 --- /dev/null +++ b/Other Algorithms/Check Wagstaff Prime/Wagstaff.cpp @@ -0,0 +1,37 @@ + +#include +using namespace std; + +bool isPrime(int n) +{ + if (n <= 1) + return false; + if (n <= 3) + return true; + if (n % 2 == 0 || n % 3 == 0) + return false; + + for (int i = 5; i * i <= n; i = i + 6) { + if (n % i == 0 || n % (i + 2) == 0) { + return false; + } + } + + return true; +} +bool isPowerOfTwo(int n) +{ + return (n && !(n & (n - 1))); +} +int main() +{ + int n = 43; + if (isPrime(n) && (isPowerOfTwo(n * 3 - 1))) { + cout << "YES\n"; + } + else { + cout << "NO\n"; + } + + return 0; +} diff --git a/Other Algorithms/ConvertFromBytes/sh/convertFromBytes.sh b/Other Algorithms/ConvertFromBytes/sh/convertFromBytes.sh new file mode 100644 index 000000000..64de89db2 --- /dev/null +++ b/Other Algorithms/ConvertFromBytes/sh/convertFromBytes.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# Script to receive a number in bytes and converto to: MiB, GiB, TiB, etc +# +# How to use: +# sh convertFromBytes.sh 1000000000 +# Result: 953.67 MiB + + +bytestohuman() { + local L_BYTES="${1:-0}" + local L_PAD="${2:-no}" + local L_BASE="${3:-1024}" + BYTESTOHUMAN_RESULT=$(awk -v bytes="${L_BYTES}" -v pad="${L_PAD}" -v base="${L_BASE}" 'function human(x, pad, base) { + if(base!=1024)base=1000 + basesuf=(base==1024)?"iB":"B" + + s="BKMGTEPYZ" + while (x>=base && length(s)>1) + {x/=base; s=substr(s,2)} + s=substr(s,1,1) + + xf=(pad=="yes") ? ((s=="B")?"%5d ":"%8.2f") : ((s=="B")?"%d":"%.2f") + s=(s!="B") ? (s basesuf) : ((pad=="no") ? s : ((basesuf=="iB")?(s " "):(s " "))) + + return sprintf( (xf " %s\n"), x, s) + } + BEGIN{print human(bytes, pad, base)}') + return $? +} + +bytestohuman "$1"; echo "${BYTESTOHUMAN_RESULT}."; diff --git a/Other Algorithms/CountWords.java b/Other Algorithms/CountWords.java new file mode 100644 index 000000000..b38c7cd95 --- /dev/null +++ b/Other Algorithms/CountWords.java @@ -0,0 +1,27 @@ +package strings; + +public class CountWords { + + static int countWords(String str) + { + int count= 0; + for(int i=0; i< str.length(); i++) + { + if(str.charAt(i) == ' ') + { + count++; + } + } + return count+1; + } + + public static void main(String[] args) { + // TODO Auto-generated method stub + + String s ="This is a test match"; + System.out.println(countWords(s)); + + + } + +} diff --git a/Other Algorithms/CountWordsTest.java b/Other Algorithms/CountWordsTest.java new file mode 100644 index 000000000..fa35a83c3 --- /dev/null +++ b/Other Algorithms/CountWordsTest.java @@ -0,0 +1,17 @@ +import static org.junit.Assert.assertEquals; + +public class CountWordsTest { + + public void testWords() { + assertEquals(4, CountWords.countWords("There are four words.")); + } + public void testNumbers() { + assertEquals(4, CountWords.countWords("There are 4 words.")); + } + public static void main(String[] args) { + CountWordsTest t = new CountWordsTest(); + t.testWords(); + t.testNumbers(); + } + +} diff --git a/Other Algorithms/Find-Longest-String-FCC/c-sharp/find-longest-string-test.cs b/Other Algorithms/Find-Longest-String-FCC/c-sharp/find-longest-string-test.cs new file mode 100644 index 000000000..0613c80be --- /dev/null +++ b/Other Algorithms/Find-Longest-String-FCC/c-sharp/find-longest-string-test.cs @@ -0,0 +1,37 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using AlgorithmService; + +namespace AlgorithmService.Tests +{ + [TestClass] + public class BasicAlgorithmServiceTests + { + private readonly BasicAlgorithmService _basicAlgorithmService; + + public BasicAlgorithmServiceTests() + { + _basicAlgorithmService = new BasicAlgorithmService(); + } + + [TestMethod] + public void FindLongestWordLength_ReturnCorrectType() + { + var result = _basicAlgorithmService.FindLongestWordLength("The quick brown fox jumped over the lazy dog"); + + Assert.IsInstanceOfType(result, typeof(int)); + } + + [DataTestMethod] + [DataRow("The quick brown fox jumped over the lazy dog", 6)] + [DataRow("May the force be with you", 5)] + [DataRow("Google do a barrel roll", 6)] + [DataRow("What is the average airspeed velocity of an unladen swallow", 8)] + [DataRow("What if we try a super-long word such as otorhinolaryngology", 19)] + public void FindLongestWordLength_ReturnCorrectValue(string input, int expected) + { + var result = _basicAlgorithmService.FindLongestWordLength(input); + + Assert.AreEqual(expected, result); + } + } +} \ No newline at end of file diff --git a/Other Algorithms/Find-Longest-String-FCC/c-sharp/find-longest-string.cs b/Other Algorithms/Find-Longest-String-FCC/c-sharp/find-longest-string.cs new file mode 100644 index 000000000..063ebe1b2 --- /dev/null +++ b/Other Algorithms/Find-Longest-String-FCC/c-sharp/find-longest-string.cs @@ -0,0 +1,18 @@ +using System.Linq; + +namespace AlgorithmService +{ + public class BasicAlgorithmService + { + public int FindLongestWordLength(string input) + { + if (string.IsNullOrWhiteSpace(input)) + throw new InvalidOperationException("Your input cannot be blank."); + + return input + .Split(' ') + .Select(w => w.Length) + .Max(); + } + } +} \ No newline at end of file diff --git a/Other Algorithms/Find-Longest-String-FCC/readme.md b/Other Algorithms/Find-Longest-String-FCC/readme.md new file mode 100644 index 000000000..0e13ee3df --- /dev/null +++ b/Other Algorithms/Find-Longest-String-FCC/readme.md @@ -0,0 +1,14 @@ +Find the Longest Word in a String + (taken from FreeCodeCamp - Basic Algorithms) + +Instructions +- Return the length of the longest word in the provided sentence. +- Your response should be a number. + +Test Scenarios +- findLongestWordLength("The quick brown fox jumped over the lazy dog") should return a number. +- findLongestWordLength("The quick brown fox jumped over the lazy dog") should return 6. +- findLongestWordLength("May the force be with you") should return 5. +- findLongestWordLength("Google do a barrel roll") should return 6. +- findLongestWordLength("What is the average airspeed velocity of an unladen swallow") should return 8. +- findLongestWordLength("What if we try a super-long word such as otorhinolaryngology") should return 19. \ No newline at end of file diff --git a/Other Algorithms/Fit_square_in_equilateral_triangle.cpp b/Other Algorithms/Fit_square_in_equilateral_triangle.cpp new file mode 100644 index 000000000..7dee85b91 --- /dev/null +++ b/Other Algorithms/Fit_square_in_equilateral_triangle.cpp @@ -0,0 +1,18 @@ + #include + #include + using namespace std; + + int main(){ + + int cases, base; + cin>>cases; + + while(cases--){ + + cin>>base; + base=(base/2)-1; + base=(base*(base+1))/2; + cout< + +using namespace std; +#define ll long long int +#define N 200002 +vector v[N]; +vector ans[N]; +vector an[N]; +int P[N][19]; +int pos[N][2]; +ll a[N]; +ll b[N]; +bool vis[N]; +int L[N]={0}; +int par[N]={0}; +int sub[N]; +vector chain[N]; +int cn=0; + +int n,m,x,y; +void dfs(int u,int p) +{ + L[u]=L[p]+1; + vis[u]=1; + par[u]=p; + for(int i=0;i= 0; i--) + if (L[p] - (1 << i) >= L[q]) + p = P[p][i]; + + if (p == q) + return p; + + for (i = log; i >= 0; i--) + if (P[p][i] != -1 && P[p][i] != P[q][i]) + p = P[p][i], q = P[q][i]; + + return par[p]; + } + + + +int main() +{ + cin>>n; + memset(vis,false,sizeof vis); + memset(vis,false,sizeof vis); + + for(int i=1;i<=n;i++)cin>>a[i]; + + for(int i=1;i<=n;i++)cin>>b[i]; + + for(int i=1;i>x>>y; + // cout<>m; + int w; + + while(m--) + { + cin>>c>>x>>y; + int z=lca(x,y); + if(c==1) + { + + while(pos[x][0]!=pos[z][0]) + { + + + t=chain[pos[x][0]][0]; + j=pos[t][0]; + k=pos[t][1]; + + ans[j][k]+=1; + j=pos[x][0]; + k=pos[x][1]+1; + ans[j][k]-=1; + x=par[t]; + + } + if(x!=z) + { + w=chain[pos[z][0]][pos[z][1]+1]; + j=pos[w][0]; + k=pos[w][1]; + ans[j][k]+=1; + j=pos[x][0]; + k=pos[x][1]+1; + ans[j][k]-=1; + + + } + while(pos[y][0]!=pos[z][0]) + { + t=chain[pos[y][0]][0]; + j=pos[t][0]; + k=pos[t][1]; + ans[j][k]+=1; + j=pos[y][0]; + k=pos[y][1]+1; + ans[j][k]-=1; + + y=par[t]; + + + } + if(y!=z) + { + + w=chain[pos[z][0]][pos[z][1]+1]; + + j=pos[w][0]; + k=pos[w][1]; + ans[j][k]+=1*1ll; + j=pos[y][0]; + k=pos[y][1]+1; + ans[j][k]-=1; + + + + } + ans[pos[z][0]][pos[z][1]]+=1; + ans[pos[z][0]][pos[z][1]+1]-=1; + + + } + else + { + + while(pos[x][0]!=pos[z][0]) + { + + t=chain[pos[x][0]][0]; + j=pos[t][0]; + k=pos[t][1]; + + an[j][k]+=1; + j=pos[x][0]; + k=pos[x][1]+1; + an[j][k]-=1; + x=par[t]; + + } + if(x!=z) + { + w=chain[pos[z][0]][pos[z][1]+1]; + + j=pos[w][0]; + k=pos[w][1]; + an[j][k]++; + j=pos[x][0]; + k=pos[x][1]+1; + an[j][k]--; + + } + while(pos[y][0]!=pos[z][0]) + { + t=chain[pos[y][0]][0]; + j=pos[t][0]; + k=pos[t][1]; + + an[j][k]++; + j=pos[y][0]; + k=pos[y][1]+1; + an[j][k]--; + y=par[t]; + + } + if(y!=z) + { + w=chain[pos[z][0]][pos[z][1]+1]; + j=pos[w][0]; + k=pos[w][1]; + an[j][k]++; + j=pos[y][0]; + k=pos[y][1]+1; + an[j][k]--; + } + an[pos[z][0]][pos[z][1]]++; + an[pos[z][0]][pos[z][1]+1]--; + + + } + } + for(i=0;i<=cn;i++) + { + for( j=0;j=1) + { + ans[i][j]+=ans[i][j-1]; + an[i][j]+=an[i][j-1]; + } + } + } + for(i=0;i<=cn;i++) + { + for(j=0;j 0) { + len = LPS[len - 1]; + } else { + LPS[i] = len; + i++; + } + } + } + + return LPS; + } +} \ No newline at end of file diff --git a/Other Algorithms/KMP/pyhton/kmpsearch.py b/Other Algorithms/KMP/pyhton/kmpsearch.py new file mode 100644 index 000000000..2478cdfb2 --- /dev/null +++ b/Other Algorithms/KMP/pyhton/kmpsearch.py @@ -0,0 +1,44 @@ +# Python program for KMP Algorithm +def KMPSearch(pat, txt): + M = len(pat) + N = len(txt) + lps = [0]*M + j = 0 + computeLPSArray(pat, M, lps) + + i = 0 + while i < N: + if pat[j] == txt[i]: + i += 1 + j += 1 + + if j == M: + print "Found pattern at index " + str(i-j) + j = lps[j-1] + elif i < N and pat[j] != txt[i]: + if j != 0: + j = lps[j-1] + else: + i += 1 + +def computeLPSArray(pat, M, lps): + len = 0 + + lps[0] + i = 1 + while i < M: + if pat[i]== pat[len]: + len += 1 + lps[i] = len + i += 1 + else: + if len != 0: + len = lps[len-1] + else: + lps[i] = 0 + i += 1 + +txt = "ABABDABACDABABCABAB" +pat = "ABABCABAB" +KMPSearch(pat, txt) + diff --git a/Other Algorithms/Kadane Algorithm/java/Kadane.java b/Other Algorithms/Kadane Algorithm/java/Kadane.java new file mode 100644 index 000000000..962b4bba1 --- /dev/null +++ b/Other Algorithms/Kadane Algorithm/java/Kadane.java @@ -0,0 +1,22 @@ +class Kadane { + + static int maxSubArraySum(int a[], int size) { + int max_so_far = a[0]; + int curr_max = a[0]; + + for (int i = 1; i < size; i++) + { + curr_max = Math.max(a[i], curr_max+a[i]); + max_so_far = Math.max(max_so_far, curr_max); + } + return max_so_far; + } + + + public static void main(String[] args) { + int a[] = {-2, -3, 4, -1, -2, 1, 5, -3}; + int n = a.length; + int max_sum = maxSubArraySum(a, n); + System.out.println("Maximum contiguous sum is " + max_sum); + } +} \ No newline at end of file diff --git a/Other Algorithms/Luhn/luhn.js b/Other Algorithms/Luhn/luhn.js new file mode 100644 index 000000000..c7dc16434 --- /dev/null +++ b/Other Algorithms/Luhn/luhn.js @@ -0,0 +1,137 @@ +class LuhnECMA6 { + + constructor(cardNo) { + + /* Preparing Variables */ + this._reverseCardNo = cardNo.split('').reverse().join(''); + this._intCardNo = Array.from(this._reverseCardNo) + .map(a => parseInt(a)); + this._value = 0; + this._filterSum = 0; + this._checkDigit = []; + this._filter1 = []; + this._filter2 = []; + this._preparedNumList = []; + this._finalNumList = []; + } + + /* Accept anything but set to array*/ + setCheckDigit(... digit){ + this._checkDigit = digit; + } + + /*Merging two arrays and output as a string*/ + getCardNo(){ + Array.prototype.push.apply(this._intCardNo.reverse(), this._checkDigit); + return this._intCardNo.join(''); + } + + /* Filtering ODD numbers*/ + getOddNumberList(){ + + let pos = 1; + this._filter1 = this._intCardNo.filter(a => { + this._value = pos % 2 != 0 + pos++; + return this._value; + }); + } + + /* Filtering EVEN numbers*/ + getEvenNumberList(){ + + let pos = 1; + this._filter2 = this._intCardNo.filter(a => { + this._value = pos % 2 == 0; + pos++; + return this._value; + }); + } + + /* Manipulating ODD numbers according to the algo.*/ + prepareOddNumbers(){ + + let x = 0; + this._preparedNumList = this._filter1.map(a => { + x = a * 2; + if(x > 9){ + x = x - 9; + } + return x; + }); + } + + /*Get total value of the sequence*/ + getTotal(){ + + this._finalNumList = this._preparedNumList.concat(this._filter2); + this._filterSum = this._finalNumList.reduce((a,b) => { + return a + b; + }); + } + + getFilterSum(){ + return this._filterSum; + } + +} + +/*=================== Execution ========================*/ + +let luhnECMA6 = new LuhnECMA6("239856745612864"); + +luhnECMA6.getOddNumberList(); +luhnECMA6.getEvenNumberList(); +luhnECMA6.prepareOddNumbers(); +luhnECMA6.getTotal(); + +let val = luhnECMA6.getFilterSum() % 10; +let checkDigit = 10 - val; + +luhnECMA6.setCheckDigit(checkDigit); + +document.write(`Check Digit : ${checkDigit}
`); +document.write(`Card Number : ${luhnECMA6.getCardNo()}
`); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Other Algorithms/Process Scheduling/java/process.java b/Other Algorithms/Process Scheduling/java/process.java new file mode 100644 index 000000000..7a944bbf7 --- /dev/null +++ b/Other Algorithms/Process Scheduling/java/process.java @@ -0,0 +1,549 @@ + +//package himsri; + +/** + * + * @author Himanshu + */ +import javax.swing.JOptionPane; +//import java.util.Scanner; +class process{ + public String name; + public int bt; + public int at; + public int prt; + public int wt,ta; + public int flag; + + public void processdata(String k,int b,int a,int p){ + this.name=k; + this.bt=b; + this.at=a; + this.prt=p; + } + +} +public class Himsri { + + public static void main(String[] args) { + + int n; + process[] p = new process[20]; + + + n=Integer.parseInt(JOptionPane.showInputDialog("Enter Number of Processes:")); + +for(int i=0;i temp7[j+1].at){ +t = temp7[j]; +temp7[j] = temp7[j+1]; +temp7[j+1] = t; +} +} +} + @SuppressWarnings("empty-statement") + static void SjfNp(process k[],int n) + { + System.out.print("\n-------------------------------------------------------------------------------------\n"); + System.out.print("SJF Non Pre-emptive"); + System.out.print("\n-------------------------------------------------------------------------------------\n"); + process []temp=new process[10]; + process t; + int sumw=0; + int sumt=0; + int x=0; + float avgwt=0; + float avgta=0; + int i,j; + + for( i=0;itemp[j+1].bt){ + t = temp[j]; + temp[j] = temp[j+1]; + temp[j+1] = t; + } + } + } + + System.out.println("PROC.\tB.T.\tA.T."); +for(i=0;in-1) + k=0; + if(temp1[k].bt>0) + System.out.print(" "+tcurr+" "+temp1[k].name); + t=0; + while(t 0){ + t++; + tcurr++; + temp1[k].bt--; + } + if(temp1[k].bt <= 0 && temp1[k].flag != 1){ + temp1[k].wt = tcurr - b[k]- temp1[k].at; + temp1[k].ta = tcurr - temp1[k].at; + pflag++; + temp1[k].flag = 1; + sumw+=temp1[k].wt; + + + sumt+=temp1[k].ta; + } + + if(pflag==n) { + break; + } else { + } + } + System.out.print(" "+tcurr); + for( i=0;i 0 && temp4[l].at <= tcurr){ + // System.out.print("c1"); + b[l]--;} + + if(l!=m){ + System.out.print(tcurr+" "+temp4[l].name+" "); + // System.out.print("c2"); + } + + if(b[l]<=0 && temp4[l].flag != 1){ + + temp4[l].flag = 1; + temp4[l].wt = (tcurr+1) - temp4[l].bt - temp4[l].at; + temp4[l].ta = (tcurr+1) - temp4[l].at; + sumw+=temp4[l].wt; + sumt+=temp4[l].ta; + // System.out.print("sumw="+sumw+" sumt"+sumt+"\n"); + } + m=l; + min_bt = 999; + for(x=0;x b[x]){ + min_bt = b[x]; + l=x; + } + } + } + + }//for + System.out.println(" "+tcurr); + /************/ + System.out.println("\n PROC.\tB.T.\tA.T.\tW.T\tT.A.T"); + for(i=0;i 0 && temp5[i].at <= tcurr) + c[i]--; + + if(i!=j) + System.out.print(tcurr+" "+temp5[i].name+" "); + + + //System.out.print("temp5 set.flag"+temp5[i].flag +"\n"); + if(c[i]<=0 && temp5[i].flag != 1) + { + temp5[i].flag = 1; + temp5[i].wt = (tcurr+1) - temp5[i].bt - temp5[i].at; + temp5[i].ta = (tcurr+1) - temp5[i].at; + sumw+=temp5[i].wt; + sumt+=temp5[i].ta; + } + j=i; + min_pr = 999; + for(x=0;x temp5[x].prt){ + + min_pr = temp5[x].prt; + i=x; + } + } + } + + }//for + + System.out.print(" "+tcurr); + + /************/ + System.out.println("\n PROC.\tB.T.\tA.T.\tW.T\tT.A.T"); + for(i=0;i temp6[j+1].prt){ + t = temp6[j]; + temp6[j] = temp6[j+1]; + temp6[j+1] = t; + } + } + + System.out.println("\n PROC.\tB.T.\tA.T.\tPRT."); + for(i=0;i +using namespace std; +int main() +{int n,rev=0,num; +cout<<"Enter the no. to be reversed :" ; +cin>>num; +while(num) +{n=num%10; +rev=rev*10+n; +num=num/10; + } + cout<<"The reverse number is "< + +int reverse_number(int x) { + int rev_x = 0; + + while (x != 0) { + rev_x = rev_x * 10 + x % 10; + x = x / 10; + } + + return rev_x; +} + +int main() { + int x; + + scanf("%d", &x); + printf("%d\n", reverse_number(x)); + + return 0; +} diff --git a/Other Algorithms/Reverse Number/rev.go b/Other Algorithms/Reverse Number/rev.go new file mode 100644 index 000000000..8405c98f1 --- /dev/null +++ b/Other Algorithms/Reverse Number/rev.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "math" +) + +func main() { + fmt.Println("Hello, playground") + num := -123 + + fmt.Println(num) + fmt.Println(reverseNumber(num)) + + num2 := 123 + + fmt.Println(num2) + fmt.Println(reverseNumber(num2)) +} + +func reverseNumber(n int) int { + if n == 0 { + return 0 + } + + negNum := false + + if n < 0 { + n = n * -1 + negNum = true + } + + lengthOfN := (int)(math.Log10(float64(n)) + 1) + newN := 0 + for i := lengthOfN; i > 0; i-- { + digit := n % 10 + n = n / 10 + for j := 1; j < i; j++ { + digit *= 10 + } + newN += digit + } + + if negNum == true { + newN *= -1 + } + return newN +} diff --git a/Other Algorithms/Reverse Polish Notation/ReversedPolishNotation.cpp b/Other Algorithms/Reverse Polish Notation/ReversedPolishNotation.cpp new file mode 100644 index 000000000..6746d9827 --- /dev/null +++ b/Other Algorithms/Reverse Polish Notation/ReversedPolishNotation.cpp @@ -0,0 +1,118 @@ +#include "stdafx.h" +#include "ReversedPolishNotation.h" +#include + + +ReversedPolishNotation::ReversedPolishNotation() +{ + precedence.emplace('n', 2); + precedence.emplace('a', 1); + precedence.emplace('o', 1); + precedence.emplace('i', 0); + association.emplace('n', RIGHT); + association.emplace('a', LEFT); + association.emplace('o', LEFT); + association.emplace('i', LEFT); + +} + + +ReversedPolishNotation::~ReversedPolishNotation() +{ +} + +string ReversedPolishNotation::convertToRPN(string s) +{ + string output; + stack operators; + stack controller; + bool seenSymbol=false, seenVariable=false; + + + while (s.length() != 0) { + char token = s.front(); + s.erase(0, 1); + if (token >= 'A'&&token <= 'Z' || token == '0' || token == '1') { + if (seenVariable) + return DOUBLED_VARIABLE_ERROR; + + output += token; + seenVariable = true; + seenSymbol = false; + } + else if(contains(token)) + { + if (seenSymbol&&token != 'n') + return DOUBLED_SYMBOL_ERROR; + seenVariable = false; + seenSymbol = true; + if (operators.size() > 0) { + char op = operators.top(); + operators.pop(); + int error = 1; + while (op != '(' && ((precedence.at(op) > precedence.at(token)) || ((precedence.at(op) == precedence.at(token)) && association.at(op) == LEFT))){ + error = 0; + output += op; + if (operators.size() > 0) { + op = operators.top(); + operators.pop(); + } + else + break; + } + if (error == 1) + operators.push(op); + operators.push(token); + } + else + operators.push(token); + } + else if (token == '(') { + if(seenVariable) + return NO_SYMBOL_PARENTHESIS_ERROR; + operators.push(token); + } + else if (token == ')') { + char op = operators.top(); + operators.pop(); + while (op != '(') { + output += op; + if (operators.size() > 0) + { + op = operators.top(); + operators.pop(); + } + else + return PARENTHESIS_ERROR; + } + } + else if(token!=' ') + return INVALID_CHARACTER_ERROR; + + } + if (operators.size() > 0) { + char op = operators.top(); + operators.pop(); + while (operators.size() > 0) { + if (op != '(') + output += op; + else + return PARENTHESIS_ERROR; + op = operators.top(); + operators.pop(); + } + if (op != '(') + output += op; + else + return PARENTHESIS_ERROR; + } + return output; +} + +bool ReversedPolishNotation::contains(char c) +{ + for (auto& x : precedence) + if (x.first == c) + return true; + return false; +} diff --git a/Other Algorithms/Reverse Polish Notation/ReversedPolishNotation.h b/Other Algorithms/Reverse Polish Notation/ReversedPolishNotation.h new file mode 100644 index 000000000..0a1a84afc --- /dev/null +++ b/Other Algorithms/Reverse Polish Notation/ReversedPolishNotation.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include +#include +using namespace std; +class ReversedPolishNotation +{ +public: + ReversedPolishNotation(); + ~ReversedPolishNotation(); + string convertToRPN(string s); +private: + const int RIGHT = 0; + const int LEFT = 1; + const string PARENTHESIS_ERROR = "ERROR PARENTHESIS: There are mismatched parentheses"; + const string NO_SYMBOL_PARENTHESIS_ERROR = "ERROR NO SYMBOL BEFORE PARENTHESIS: You have to put a symbol ('a','o','i','n','(') before the parenthesis"; + const string DOUBLED_SYMBOL_ERROR = "ERROR DOUBLED SYMBOL: You have to put a variable after any symbol, except for 'n' and '('"; + const string DOUBLED_VARIABLE_ERROR = "ERROR DOUBLED VARIABLE: You have to put a symbol after any variable"; + const string INVALID_CHARACTER_ERROR = "ERROR INVALID CHARACTER: You have to put variables like [A...Z] || (0,1) and symbols like a || n || o || i || ( || )"; + map precedence; + map association; + bool contains(char c); + +}; + diff --git a/Other Algorithms/Reverse Sentence/Go/reverse_sentence_and_string.go b/Other Algorithms/Reverse Sentence/Go/reverse_sentence_and_string.go new file mode 100644 index 000000000..fb5ac2a9b --- /dev/null +++ b/Other Algorithms/Reverse Sentence/Go/reverse_sentence_and_string.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + "strings" +) + +func main() { + sentence := "Hello World" + + fmt.Println(sentence) + fmt.Println(reverseSentence(sentence)) + fmt.Println(reverseString(sentence)) +} + +func reverseSentence(str string) string { + words := strings.Split(str, " ") + for i := len(words)/2 - 1; i >= 0; i-- { + opposite := len(words) - i - 1 + words[i], words[opposite] = words[opposite], words[i] + } + return strings.Join(words, " ") +} + +func reverseString(str string) string { + runes := []rune(str) + for i := len(runes)/2 - 1; i >= 0; i-- { + opposite := len(runes) - i - 1 + runes[i], runes[opposite] = runes[opposite], runes[i] + } + return string(runes) +} diff --git a/Other Algorithms/Reverse Sentence/JavaScript/reverse.js b/Other Algorithms/Reverse Sentence/JavaScript/reverse.js new file mode 100644 index 000000000..cb300b317 --- /dev/null +++ b/Other Algorithms/Reverse Sentence/JavaScript/reverse.js @@ -0,0 +1,16 @@ +function reverseString(str) { + var newString = ""; + for (var i = str.length - 1; i >= 0; i--) { + newString += str[i]; + } + return newString; +} +reverseString('hello'); + + +//and for a more js way: + +function reverseString(str) { + return str.split("").reverse().join(""); +} +reverseString("hello"); \ No newline at end of file diff --git a/Other Algorithms/Reverse Sentence/Reverse.java b/Other Algorithms/Reverse Sentence/Reverse.java new file mode 100644 index 000000000..1d9584850 --- /dev/null +++ b/Other Algorithms/Reverse Sentence/Reverse.java @@ -0,0 +1,34 @@ +package strings; + +public class Reverse { + + static String reverseEachWord(String input) + { + String words[] = input.split("\\s"); + String revstring = ""; + + for(int i=0; i=0; j--) + { + s += indiword.charAt(j); + } + + revstring = revstring + s + " "; + + } + + return revstring; + } + + public static void main(String[] args) + { + String str ="Welcome to coding ninjas"; + System.out.println(reverseEachWord(str)); + + } + +} diff --git a/Other Algorithms/Reverse-A-String-FCC/JavaScript/reverseString.js b/Other Algorithms/Reverse-A-String-FCC/JavaScript/reverseString.js new file mode 100644 index 000000000..51ba97b13 --- /dev/null +++ b/Other Algorithms/Reverse-A-String-FCC/JavaScript/reverseString.js @@ -0,0 +1,36 @@ +/** + * Long Method + */ +// const reverseString = (str) => { +// let newStr = ""; +// for(let i=str.length-1; i>=0; i--){ +// newStr=newStr+str[i]; +// } +// console.log(newStr); +// console.log(str); +// } + +/** + * Using Recursion + */ +// function reverseString(str){ +// if(str === "") +// return ""; +// else { +// return reverseString(str.substr(1)) + str.charAt(0); +// } +// } + +/** + * Shortcut Method + */ +function reverseString(str){ + if(str === "") + return ""; + else { + return str.split("").reverse().join(""); + } +} + +console.log(reverseString("hello")); +console.log(reverseString("apple")); diff --git a/Other Algorithms/Reverse-A-String-FCC/c-sharp/reverse-a-string-test.cs b/Other Algorithms/Reverse-A-String-FCC/c-sharp/reverse-a-string-test.cs new file mode 100644 index 000000000..322f7f3fa --- /dev/null +++ b/Other Algorithms/Reverse-A-String-FCC/c-sharp/reverse-a-string-test.cs @@ -0,0 +1,35 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using AlgorithmService; + +namespace AlgorithmService.Tests +{ + [TestClass] + public class BasicAlgorithmServiceTests + { + private readonly BasicAlgorithmService _basicAlgorithmService; + + public BasicAlgorithmServiceTests() + { + _basicAlgorithmService = new BasicAlgorithmService(); + } + + [TestMethod] + public void ReverseString_ReturnCorrectType() + { + var result = _basicAlgorithmService.ReverseString("hello"); + + Assert.IsInstanceOfType(result, typeof(string)); + } + + [DataTestMethod] + [DataRow("hello", "olleh")] + [DataRow("Howdy", "ydwoH")] + [DataRow("Greetings from Earth", "htraE morf sgniteerG")] + public void ReverseString_ReturnCorrectValue(string input, string expected) + { + var result = _basicAlgorithmService.ReverseString(input); + + Assert.AreEqual(expected, result); + } + } +} \ No newline at end of file diff --git a/Other Algorithms/Reverse-A-String-FCC/c-sharp/reverse-a-string.cs b/Other Algorithms/Reverse-A-String-FCC/c-sharp/reverse-a-string.cs new file mode 100644 index 000000000..f6ca48227 --- /dev/null +++ b/Other Algorithms/Reverse-A-String-FCC/c-sharp/reverse-a-string.cs @@ -0,0 +1,17 @@ + +namespace AlgorithmService +{ + public class BasicAlgorithmService + { + public string ReverseString(string original) + { + if (original == null) + throw new ArgumentNullException(nameof(original)); + + if (original.Length == 0) + return ""; + + return string.Join("", original.ToCharArray().Reverse()); + } + } +} diff --git a/Other Algorithms/Reverse-A-String-FCC/readme.md b/Other Algorithms/Reverse-A-String-FCC/readme.md new file mode 100644 index 000000000..6a2e6ad0d --- /dev/null +++ b/Other Algorithms/Reverse-A-String-FCC/readme.md @@ -0,0 +1,13 @@ +Reverse a string + (taken from FreeCodeCamp - Basic Algorithms) + +Instructions +- Reverse the provided string. +- You may need to turn the string into an array before you can reverse it. +- Your result must be a string. + +Test Scenarios +- reverseString("hello") should return a string. +- reverseString("hello") should become "olleh" +- reverseString("Howdy") should become "ydwoH" +- reverseString("Greetings from Earth") should return "htraE morf sgniteerG" \ No newline at end of file diff --git a/Other Algorithms/Second-Max-Min-in-SubArray/second-max-min.cpp b/Other Algorithms/Second-Max-Min-in-SubArray/second-max-min.cpp new file mode 100644 index 000000000..df3bbfbf2 --- /dev/null +++ b/Other Algorithms/Second-Max-Min-in-SubArray/second-max-min.cpp @@ -0,0 +1,42 @@ +#include +#include +using namespace std; + +int calculate(int a[],int start,int endd){ + cout<<"start-"<max1){ + max2=max1; + max1=a[i]; + } + else if(a[i]>max2 && a[i]!=max1){ + max2=a[i]; + } + } + for(i=start;i<=endd;i++){ + if(a[i]>n>>k; + int a[n]; + for(i=0;i>a[i]; + } + for(i=0,j=k-1;j 0: + L[i] = min(L[iMirror], diff) + + # Attempt to expand palindrome centered at currentRightPosition i + # Here for odd positions, we compare characters and + # if match then increment LPS Length by ONE + # If even position, we just increment LPS by ONE without + # any character comparison + try: + while ((i + L[i]) < N and (i - L[i]) > 0) and \ + (((i + L[i] + 1) % 2 == 0) or \ + (text[(i + L[i] + 1) / 2] == text[(i - L[i] - 1) / 2])): + L[i]+=1 + except Exception as e: + pass + + if L[i] > maxLPSLength: # Track maxLPSLength + maxLPSLength = L[i] + maxLPSCenterPosition = i + + # If palindrome centered at currentRightPosition i + # expand beyond centerRightPosition R, + # adjust centerPosition C based on expanded palindrome. + if i + L[i] > R: + C = i + R = i + L[i] + + # Uncomment it to print LPS Length array + # printf("%d ", L[i]); + start = (maxLPSCenterPosition - maxLPSLength) / 2 + end = start + maxLPSLength - 1 + print "LPS of string is " + text + " : ", + print text[start:end+1], + print "\n", + +# Driver program +text1 = "babcbabcbaccba" +findLongestPalindromicString(text1) + +text2 = "abaaba" +findLongestPalindromicString(text2) + +text3 = "abababa" +findLongestPalindromicString(text3) + +text4 = "abcbabcbabcba" +findLongestPalindromicString(text4) + +text5 = "forgeeksskeegfor" +findLongestPalindromicString(text5) + +text6 = "caba" +findLongestPalindromicString(text6) + +text7 = "abacdfgdcaba" +findLongestPalindromicString(text7) + +text8 = "abacdfgdcabba" +findLongestPalindromicString(text8) + +text9 = "abacdedcaba" +findLongestPalindromicString(text9) \ No newline at end of file diff --git a/Other Algorithms/String/manachers algorithm/manacher algorithm.txt b/Other Algorithms/String/manachers algorithm/manacher algorithm.txt new file mode 100644 index 000000000..5905eb422 --- /dev/null +++ b/Other Algorithms/String/manachers algorithm/manacher algorithm.txt @@ -0,0 +1,89 @@ +def findLongestPalindromicString(text): + N = len(text) + if N == 0: + return + N = 2*N+1 # Position count + L = [0] * N + L[0] = 0 + L[1] = 1 + C = 1 # centerPosition + R = 2 # centerRightPosition + i = 0 # currentRightPosition + iMirror = 0 # currentLeftPosition + maxLPSLength = 0 + maxLPSCenterPosition = 0 + start = -1 + end = -1 + diff = -1 + + # Uncomment it to print LPS Length array + # printf("%d %d ", L[0], L[1]); + for i in xrange(2,N): + + # get currentLeftPosition iMirror for currentRightPosition i + iMirror = 2*C-i + L[i] = 0 + diff = R - i + # If currentRightPosition i is within centerRightPosition R + if diff > 0: + L[i] = min(L[iMirror], diff) + + # Attempt to expand palindrome centered at currentRightPosition i + # Here for odd positions, we compare characters and + # if match then increment LPS Length by ONE + # If even position, we just increment LPS by ONE without + # any character comparison + try: + while ((i + L[i]) < N and (i - L[i]) > 0) and \ + (((i + L[i] + 1) % 2 == 0) or \ + (text[(i + L[i] + 1) / 2] == text[(i - L[i] - 1) / 2])): + L[i]+=1 + except Exception as e: + pass + + if L[i] > maxLPSLength: # Track maxLPSLength + maxLPSLength = L[i] + maxLPSCenterPosition = i + + # If palindrome centered at currentRightPosition i + # expand beyond centerRightPosition R, + # adjust centerPosition C based on expanded palindrome. + if i + L[i] > R: + C = i + R = i + L[i] + + # Uncomment it to print LPS Length array + # printf("%d ", L[i]); + start = (maxLPSCenterPosition - maxLPSLength) / 2 + end = start + maxLPSLength - 1 + print "LPS of string is " + text + " : ", + print text[start:end+1], + print "\n", + +# Driver program +text1 = "babcbabcbaccba" +findLongestPalindromicString(text1) + +text2 = "abaaba" +findLongestPalindromicString(text2) + +text3 = "abababa" +findLongestPalindromicString(text3) + +text4 = "abcbabcbabcba" +findLongestPalindromicString(text4) + +text5 = "forgeeksskeegfor" +findLongestPalindromicString(text5) + +text6 = "caba" +findLongestPalindromicString(text6) + +text7 = "abacdfgdcaba" +findLongestPalindromicString(text7) + +text8 = "abacdfgdcabba" +findLongestPalindromicString(text8) + +text9 = "abacdedcaba" +findLongestPalindromicString(text9) \ No newline at end of file diff --git a/Other Algorithms/String/python/ahocorasick.py b/Other Algorithms/String/python/ahocorasick.py new file mode 100644 index 000000000..942be1122 --- /dev/null +++ b/Other Algorithms/String/python/ahocorasick.py @@ -0,0 +1,157 @@ +import unittest +from collections import deque, defaultdict + +class AhoCorasick: + def __init__(self, keywords): + self.state = 0 + self.built = False + self.keywords = keywords + self.num_nodes = 1 + + # We use a defaultdict with default of 0 to handle + # the loop from node 0 to itself when unknown + # characters are given. + self.goto = [defaultdict(int)] + self.fail = [0] + self.output = [set()] + + def build(self): + # We begin by building the goto function + for keyword in self.keywords: + cur_node = 0 + for letter in keyword: + # If a path exists for this part of the word, continue along it + if letter in self.goto[cur_node]: + cur_node = self.goto[cur_node][letter] + + # Otherwise we need to create a new node + else: + self.goto[cur_node][letter] = self.num_nodes + self.goto.append(defaultdict(int)) + self.output.append(set()) + cur_node = self.num_nodes + self.num_nodes += 1 + + # Update the output with the full keyword + self.output[cur_node] = set([keyword]) + + # To create the fail function we need to iteratively move up the tree + # starting with nodes that have depth 1, then 2, and so on + + # We initialise all nodes to fail to the root + self.fail = [0 for _ in range(self.num_nodes)] + + # Fill the queue with nodes of depth 1 + queue = deque() + for a, s in self.goto[0].items(): + queue.append(s) + self.fail[s] = 0 + + # Construct the fail function + while len(queue) != 0: + r = queue.popleft() + for a, s in self.goto[r].items(): + queue.append(s) + state = self.fail[r] + + # Fail back until we can move back up a chain + while a not in self.goto[state] and state != 0: + state = self.fail[state] + + self.fail[s] = self.goto[state][a] + + # Update output for substrings, e.g. add "he" to output + # in the same spot as where "she" ends + self.output[s] = self.output[s].union(self.output[self.fail[s]]) + + # Mark the graph as built + self.built = True + + def search(self, corpus): + if not self.built: + raise Exception("You need to build the graph before searching corpuses.") + + cur_node = 0 + freqs = defaultdict(int) + + # Each letter corresponds to one state change + for letter in corpus: + # Fail back until we can move up a chain + while letter not in self.goto[cur_node] and cur_node != 0: + cur_node = self.fail[cur_node] + + cur_node = self.goto[cur_node][letter] + + # Record keywords at this point in our dictionary + for keyword in self.output[cur_node]: + freqs[keyword] += 1 + + return freqs + +class TestAhoCorasick(unittest.TestCase): + def test_paper_example(self): + corpus = 'ushers' + keywords = ['he', 'she', 'his', 'hers'] + expected = { + 'he' : 1, + 'hers': 1, + 'she' : 1, + } + + ac = AhoCorasick(keywords) + ac.build() + actual = ac.search(corpus) + + self.assertEqual(actual, expected) + + def test_wikipedia_example(self): + corpus = 'abccab' + keywords = ['a', 'ab', 'bab', 'bc', 'bca', 'c', 'caa'] + expected = { + 'a' : 2, + 'ab': 2, + 'bc': 1, + 'c' : 2, + } + + ac = AhoCorasick(keywords) + ac.build() + actual = ac.search(corpus) + + self.assertEqual(actual, expected) + + def test_simple_all_substrings(self): + corpus = 'abc' + keywords = ['a', 'b', 'c', 'ab', 'bc', 'abc'] + expected = { + 'a' : 1, + 'b' : 1, + 'c' : 1, + 'ab' : 1, + 'bc' : 1, + 'abc': 1, + } + + ac = AhoCorasick(keywords) + ac.build() + actual = ac.search(corpus) + + self.assertEqual(actual, expected) + + def test_nonalpha_chars(self): + corpus = 'I think she said, "the quick brown dog jumps over the lazy dog", maybe!' + keywords = ['the', 'dog', 'he'] + expected = { + 'the': 2, + 'dog': 2, + 'he' : 3, + } + + ac = AhoCorasick(keywords) + ac.build() + actual = ac.search(corpus) + + self.assertEqual(actual, expected) + +if __name__ == '__main__': + unittest.main() diff --git a/Other Algorithms/String/python/another_string_reverse.py b/Other Algorithms/String/python/another_string_reverse.py new file mode 100644 index 000000000..78b2e6bef --- /dev/null +++ b/Other Algorithms/String/python/another_string_reverse.py @@ -0,0 +1,13 @@ +def reverse(s): + str = "" + for i in s: + str = i + str + return str + +s = input("Enter the string: ") + +print ("The original string is : ",end="") +print (s) + +print ("The reversed string(using loops) is : ",end="") +print (reverse(s)) diff --git a/Other Algorithms/Suffix Automaton/CPP/SA.cpp b/Other Algorithms/Suffix Automaton/CPP/SA.cpp new file mode 100644 index 000000000..d6a098ae4 --- /dev/null +++ b/Other Algorithms/Suffix Automaton/CPP/SA.cpp @@ -0,0 +1,48 @@ +#include +#define MAX 1000007 + +using namespace std; + +struct node{ + int link, len; + map next; +} st[MAX]; + +int sz, last; + +void init(){ + sz = 1; + last = 0; + st[0].len = 0; + st[0].link = -1; + st[0].next.clear(); +} + +void add(char c){ + int cur = sz++; + st[cur].len = st[last].len + 1; + + for(; last != -1 && !st[last].next[c]; last = st[last].link) st[last].next[c] = cur; + + if(last == -1) st[cur].link = 0; + else{ + int q = st[last].next[c]; + if(st[q].len == st[last].len + 1) st[cur].link = q; + else{ + int clone = sz++; + st[clone].len = st[last].len + 1; + st[clone].link = st[q].link; + st[clone].next = st[q].next; + + for(; last != -1 && st[last].next[c] == q; last = st[last].link) st[last].next[c] = clone; + st[q].link = st[cur].link = clone; + } + } + last = cur; +} +int main(){ + string palavra; cin >> palavra; + init(); + for(int i = 0; i < palavra.size(); i++) add(palavra[i]); + return 0; +} \ No newline at end of file diff --git a/Other Algorithms/checkParent.js b/Other Algorithms/checkParent.js new file mode 100644 index 000000000..f2543faf2 --- /dev/null +++ b/Other Algorithms/checkParent.js @@ -0,0 +1,14 @@ +// Una funcion que devuelve true/false si tiene la misma cantidad de "(" y de ")" + +function checkParent (str) { + +var result = str.split("").reduce(function (previus,char) { + if (char === "(" ) { return ++previus; } + if (char === ")" ) { return --previus; } + return previus; +},0); + return !Boolean(result); +} + + +console.log(checkParent("(((())")); diff --git a/Other Algorithms/conversion.cpp b/Other Algorithms/conversion.cpp new file mode 100644 index 000000000..1996010ee --- /dev/null +++ b/Other Algorithms/conversion.cpp @@ -0,0 +1,60 @@ +#include +#include +using namespace std; +int main() +{int n; +string c; +long octal(int); +long binary(int); +string hexa(int); +cout<<"Enter the no. to convert :"; +cin>>n; + + +cout<<"Binary Equivalent :"<=0;j--) + { str2=str2+str[j]; + } + return str2; + } diff --git a/Other Algorithms/isPalindrome.c b/Other Algorithms/isPalindrome.c new file mode 100644 index 000000000..b20240bd7 --- /dev/null +++ b/Other Algorithms/isPalindrome.c @@ -0,0 +1,25 @@ +#include + +int reverse_number(int x) { + int rev_x = 0; + + while (x != 0) { + rev_x = rev_x * 10 + x % 10; + x = x / 10; + } + + return rev_x; +} + +int isPalindrome(int x) { + return reverse_number(x) == x; +} + +int main() { + int x; + + scanf("%d", &x); + printf("%d\n", isPalindrome(x)); + + return 0; +} diff --git a/Other Algorithms/isPalindrome.py b/Other Algorithms/isPalindrome.py new file mode 100644 index 000000000..9aab02f8f --- /dev/null +++ b/Other Algorithms/isPalindrome.py @@ -0,0 +1,14 @@ +def is_palindrome(x): + s = str(x) + if s == s[::-1]: + return True + return False + + +def main(): + x = int(input()) + print(str(x) + " is palindrome: " + str(is_palindrome(x))) + + +if __name__ == '__main__': + main() diff --git a/Other Algorithms/isPrime.c b/Other Algorithms/isPrime.c new file mode 100644 index 000000000..9fda45261 --- /dev/null +++ b/Other Algorithms/isPrime.c @@ -0,0 +1,23 @@ +#include + +int isPrime(int x) { + if (x == 0 || x == 1) { + return 0; + } + + for (int i = 2; i < x / 2; ++i) { + if (x % i == 0) { + return 0; + } + } + + return 1; +} + +int main() { + int x; + + scanf("%d", &x); + printf("%d\n", isPrime(x)); + return 0; +} \ No newline at end of file diff --git a/Other Algorithms/isPrime.cs b/Other Algorithms/isPrime.cs new file mode 100644 index 000000000..7bd5f9e09 --- /dev/null +++ b/Other Algorithms/isPrime.cs @@ -0,0 +1,8 @@ +public static bool isPrime(int num) { + for (int i = 2; i <= num; i++) { + if((num%i) == 0 && num != i) { + return false; + } + } + return true; +} diff --git a/Other Algorithms/isPrime.go b/Other Algorithms/isPrime.go new file mode 100644 index 000000000..876ae1c38 --- /dev/null +++ b/Other Algorithms/isPrime.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" +) + +func main() { + status := isPrime(42) + fmt.Println(status) +} + +func isPrime(value int) bool { + for i := 2; i <= value; i++ { + if value%i == 0 && i != value { + return false + } + } + return true +} diff --git a/Other Algorithms/isPrime.js b/Other Algorithms/isPrime.js new file mode 100644 index 000000000..375e4f13a --- /dev/null +++ b/Other Algorithms/isPrime.js @@ -0,0 +1,14 @@ + +// La función booleana devuelve true/false en dependencia de si el número pasado es o no primo + + function isPrime(number){ + + for (i = 2; i <= number; i++){ + if(number % i === 0 && number!= i){ + return false; + } + } + return true; + } + +console.log(isPrime(9)); diff --git a/Other Algorithms/isPrime.py b/Other Algorithms/isPrime.py new file mode 100644 index 000000000..8d688267b --- /dev/null +++ b/Other Algorithms/isPrime.py @@ -0,0 +1,18 @@ +def is_prime(x): + if x < 2: + return False + if x > 2 and x % 2 == 0: + return False + for i in range(3, int(x ** 0.5), 2): + if x % i == 0: + return False + return True + + +def main(): + x = int(input()) + print(str(x) + " is prime: " + str(is_prime(x))) + + +if __name__ == '__main__': + main() diff --git a/Other Algorithms/manachers algorithm/manacher algorithm.py b/Other Algorithms/manachers algorithm/manacher algorithm.py new file mode 100644 index 000000000..5905eb422 --- /dev/null +++ b/Other Algorithms/manachers algorithm/manacher algorithm.py @@ -0,0 +1,89 @@ +def findLongestPalindromicString(text): + N = len(text) + if N == 0: + return + N = 2*N+1 # Position count + L = [0] * N + L[0] = 0 + L[1] = 1 + C = 1 # centerPosition + R = 2 # centerRightPosition + i = 0 # currentRightPosition + iMirror = 0 # currentLeftPosition + maxLPSLength = 0 + maxLPSCenterPosition = 0 + start = -1 + end = -1 + diff = -1 + + # Uncomment it to print LPS Length array + # printf("%d %d ", L[0], L[1]); + for i in xrange(2,N): + + # get currentLeftPosition iMirror for currentRightPosition i + iMirror = 2*C-i + L[i] = 0 + diff = R - i + # If currentRightPosition i is within centerRightPosition R + if diff > 0: + L[i] = min(L[iMirror], diff) + + # Attempt to expand palindrome centered at currentRightPosition i + # Here for odd positions, we compare characters and + # if match then increment LPS Length by ONE + # If even position, we just increment LPS by ONE without + # any character comparison + try: + while ((i + L[i]) < N and (i - L[i]) > 0) and \ + (((i + L[i] + 1) % 2 == 0) or \ + (text[(i + L[i] + 1) / 2] == text[(i - L[i] - 1) / 2])): + L[i]+=1 + except Exception as e: + pass + + if L[i] > maxLPSLength: # Track maxLPSLength + maxLPSLength = L[i] + maxLPSCenterPosition = i + + # If palindrome centered at currentRightPosition i + # expand beyond centerRightPosition R, + # adjust centerPosition C based on expanded palindrome. + if i + L[i] > R: + C = i + R = i + L[i] + + # Uncomment it to print LPS Length array + # printf("%d ", L[i]); + start = (maxLPSCenterPosition - maxLPSLength) / 2 + end = start + maxLPSLength - 1 + print "LPS of string is " + text + " : ", + print text[start:end+1], + print "\n", + +# Driver program +text1 = "babcbabcbaccba" +findLongestPalindromicString(text1) + +text2 = "abaaba" +findLongestPalindromicString(text2) + +text3 = "abababa" +findLongestPalindromicString(text3) + +text4 = "abcbabcbabcba" +findLongestPalindromicString(text4) + +text5 = "forgeeksskeegfor" +findLongestPalindromicString(text5) + +text6 = "caba" +findLongestPalindromicString(text6) + +text7 = "abacdfgdcaba" +findLongestPalindromicString(text7) + +text8 = "abacdfgdcabba" +findLongestPalindromicString(text8) + +text9 = "abacdedcaba" +findLongestPalindromicString(text9) \ No newline at end of file diff --git a/Other Algorithms/manachers algorithm/manacher algorithm.txt b/Other Algorithms/manachers algorithm/manacher algorithm.txt new file mode 100644 index 000000000..5905eb422 --- /dev/null +++ b/Other Algorithms/manachers algorithm/manacher algorithm.txt @@ -0,0 +1,89 @@ +def findLongestPalindromicString(text): + N = len(text) + if N == 0: + return + N = 2*N+1 # Position count + L = [0] * N + L[0] = 0 + L[1] = 1 + C = 1 # centerPosition + R = 2 # centerRightPosition + i = 0 # currentRightPosition + iMirror = 0 # currentLeftPosition + maxLPSLength = 0 + maxLPSCenterPosition = 0 + start = -1 + end = -1 + diff = -1 + + # Uncomment it to print LPS Length array + # printf("%d %d ", L[0], L[1]); + for i in xrange(2,N): + + # get currentLeftPosition iMirror for currentRightPosition i + iMirror = 2*C-i + L[i] = 0 + diff = R - i + # If currentRightPosition i is within centerRightPosition R + if diff > 0: + L[i] = min(L[iMirror], diff) + + # Attempt to expand palindrome centered at currentRightPosition i + # Here for odd positions, we compare characters and + # if match then increment LPS Length by ONE + # If even position, we just increment LPS by ONE without + # any character comparison + try: + while ((i + L[i]) < N and (i - L[i]) > 0) and \ + (((i + L[i] + 1) % 2 == 0) or \ + (text[(i + L[i] + 1) / 2] == text[(i - L[i] - 1) / 2])): + L[i]+=1 + except Exception as e: + pass + + if L[i] > maxLPSLength: # Track maxLPSLength + maxLPSLength = L[i] + maxLPSCenterPosition = i + + # If palindrome centered at currentRightPosition i + # expand beyond centerRightPosition R, + # adjust centerPosition C based on expanded palindrome. + if i + L[i] > R: + C = i + R = i + L[i] + + # Uncomment it to print LPS Length array + # printf("%d ", L[i]); + start = (maxLPSCenterPosition - maxLPSLength) / 2 + end = start + maxLPSLength - 1 + print "LPS of string is " + text + " : ", + print text[start:end+1], + print "\n", + +# Driver program +text1 = "babcbabcbaccba" +findLongestPalindromicString(text1) + +text2 = "abaaba" +findLongestPalindromicString(text2) + +text3 = "abababa" +findLongestPalindromicString(text3) + +text4 = "abcbabcbabcba" +findLongestPalindromicString(text4) + +text5 = "forgeeksskeegfor" +findLongestPalindromicString(text5) + +text6 = "caba" +findLongestPalindromicString(text6) + +text7 = "abacdfgdcaba" +findLongestPalindromicString(text7) + +text8 = "abacdfgdcabba" +findLongestPalindromicString(text8) + +text9 = "abacdedcaba" +findLongestPalindromicString(text9) \ No newline at end of file diff --git a/Other Algorithms/nth_fibonacci_number.py b/Other Algorithms/nth_fibonacci_number.py new file mode 100644 index 000000000..a7ab72b46 --- /dev/null +++ b/Other Algorithms/nth_fibonacci_number.py @@ -0,0 +1,19 @@ +# This program takes n as input +# It will display the nth number in the fibonacci series +# It uses recursion + +def Fibonacci(n): + if n < 0: + print("Please provide the value of n > 0") + elif n == 1: + return 0 + elif n == 2: + return 1 + else: + return Fibonacci(n-1) + Fibonacci(n-2) + +print('''Welcome! This program takes \'n\' as input +and it will print the n-th number in the Fibonacci series...''') +n = int(input("Enter the value of n - ")) +print(Fibonacci(n)) + diff --git a/Other Algorithms/num_to_words.cpp b/Other Algorithms/num_to_words.cpp new file mode 100644 index 000000000..f3da4d9ab --- /dev/null +++ b/Other Algorithms/num_to_words.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +using namespace std; + +string digitName(int digit); +string teenName(int number); +string tensName(int number); +string intName(int number); + +vector ones{ "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; +vector teens{"ten", "eleven", "twelve", "thirteen", "fourteen","fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}; +vector tens{ "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; + +string nameForNumber(long number) +{ + if (number < 10) { + return ones[number]; + } else if (number < 20) { + return teens[number - 10]; + } else if (number < 100) { + return tens[number / 10] + ((number % 10 != 0) ? " " + nameForNumber(number % 10) : ""); + } else if (number < 1000) { + return nameForNumber(number / 100) + " hundred" + ((number % 100 != 0) ? " " + nameForNumber(number % 100) : ""); + } else if (number < 1000000) { + return nameForNumber(number / 1000) + " thousand" + ((number % 1000 != 0) ? " " + nameForNumber(number % 1000) : ""); + } else if (number < 1000000000) { + return nameForNumber(number / 1000000) + " million" + ((number % 1000000 != 0) ? " " + nameForNumber(number % 1000000) : ""); + } else if (number < 1000000000000) { + return nameForNumber(number / 1000000000) + " billion" + ((number % 1000000000 != 0) ? " " + nameForNumber(number % 1000000000) : ""); + } else + return "error"; +} + + +int main() +{ + long input; + do { + cout << "Please enter a integer (Press a 0 to exit): "; + cin >> input; + if (input < 0) { + input *= -1; + cout << "\nnegative " << nameForNumber(input) << endl; + } else { + cout << "\n" << nameForNumber(input) << endl; + } + } while (input); + return 0; +} diff --git a/Other Algorithms/phoneCheck.js b/Other Algorithms/phoneCheck.js new file mode 100644 index 000000000..ef3aad5ec --- /dev/null +++ b/Other Algorithms/phoneCheck.js @@ -0,0 +1,10 @@ + +// Valida si el numero de telefono es validdo para EU + +function phoneCheck(str) { + + var exp = /^(1\s?)?(\(\d{3}\)|\d{3})[\s\-]?\d{3}[\s\-]?\d{4}$/; + return exp.test(str); +} + +console.log(phoneCheck("555-555-5555")); diff --git a/Outros Algoritmos/AVl-Tree b/Outros Algoritmos/AVl-Tree new file mode 100644 index 000000000..b5d46082e --- /dev/null +++ b/Outros Algoritmos/AVl-Tree @@ -0,0 +1,185 @@ +#include +#include + +typedef struct nod{ + + int key; + int nodecountL; + int nodecountR; + int height; + struct nod *left; + struct nod *right; +}Node; + +typedef struct{ + + Node *root; +}BST; + +BST *create_bst(){ + + BST *bst; + + bst = (BST *) malloc(sizeof(BST)); + bst->root = NULL; + + return bst; +} + +int max(int a,int b){ + + if(a>b) return a; + else return b; +} + +int height(Node *node){ + + if(node==NULL) return -1; + else return node->height; +} + +int total(Node *node){ + + if(node==NULL) return 0; + else return (1+(node->nodecountL) + (node->nodecountR)); +} + +Node *leftRotate(Node *node){ + + Node *r,*rl; + + r = node->right; + rl = r->left; + r->left = node; + node->right = rl; + node->nodecountR = total(rl); + r->nodecountL = total(node); + node->height = max(height(node->left),height(node->right)) + 1; + r->height = max(height(r->left),height(r->right)) + 1; + + return r; +} + +Node *rightRotate(Node *node){ + + Node *l,*lr; + + l = node->left; + lr = l->right; + l->right = node; + node->left = lr; + node->nodecountL = total(lr); + l->nodecountR = total(node); + node->height = max(height(node->left),height(node->right)) + 1; + l->height = max(height(l->left),height(l->right)) + 1; + + return l; +} + +Node *inserthelp(Node *node,int x){ + + int balance; + if(node==NULL){ + node = (Node *) malloc(sizeof(Node)); + node->key = x; + node->nodecountL = 0; + node->nodecountR = 0; + node->height = 0; + node->left = NULL; + node->right = NULL; + return node; + } + if(x < node->key){ + node->left = inserthelp(node->left,x); + node->nodecountL++; + } + else{ + node->right = inserthelp(node->right,x); + node->nodecountR++; + } + node->height = max(height(node->left),height(node->right)) + 1; + balance = height(node->left) - height(node->right); + if(balance > 1 && x < (node->left->key)){ + node = rightRotate(node); + } + else if(balance < -1 && x > (node->right->key)){ + node = leftRotate(node); + } + else if(balance > 1 && x > (node->left->key)){ + node->left = leftRotate(node->left); + node = rightRotate(node); + } + else if(balance < -1 && x < (node->right->key)){ + node->right = rightRotate(node->right); + node = leftRotate(node); + } + + return node; + +} + +void insert(BST *bst,int x){ + + bst->root = inserthelp(bst->root,x); +} + +int findhelp(Node *node,int x,int value){ + + if(node==NULL) return -1; + if(node->key == x) return (value+(node->nodecountL)+1); + else if(x > node->key){ + value+= (total(node->left) + 1); + return findhelp(node->right,x,value); + } + else{ + return findhelp(node->left,x,value); + } +} + +int find(BST *bst,int x){ + + return findhelp(bst->root,x,0); +} + +Node *apagar(Node *node){ + + if(node==NULL) return NULL; + node->left = apagar(node->left); + node->right = apagar(node->right); + free(node); + return NULL; +} + +void clear(BST *bst){ + + bst->root = apagar(bst->root); +} + + +int main(){ + + BST *bst; + int q,op,x,i,st; + + bst = create_bst(); + scanf("%d",&q); + for(int i=0;i +using namespace std; + +const int mod = 100000007; + +int main(){ + + vector A; + vector B; + int dp[1005][1024]; + + int tc; + int z = 1; + cin >> tc; + while(tc--){ + A.clear(); + B.clear(); + int n,m; + cin >> n >> m; + A.resize(n); B.resize(m); + for(int i=0;i> A[i]; + } + for(int i=0;i> B[i]; + } + sort(B.begin(),B.end()); + for(int i=0;i<=n;i++){ + for(int j=0;j<1024;j++){ + dp[i][j] = 0; + } + } + dp[0][0] = 1; + for(int i=1;i<=n;i++){ + int a = A[i-1]; + for(int j=0;j<1024;j++){ + dp[i][j] = (dp[i-1][j] + dp[i-1][j^a])%mod; + dp[i][j] %= mod; + } + } + B.push_back(1025); + int curr = 0; + int ans = 0; + for(int i=0;i<1024;i++){ + if(i == B[curr]){ + curr++; + } + else{ + ans += dp[n][i]; + ans %= mod; + } + } + cout << "Case " << z++ << ": " << ans << endl; + } +} diff --git a/Outros Algoritmos/maskBits b/Outros Algoritmos/maskBits new file mode 100644 index 000000000..aba0f1709 --- /dev/null +++ b/Outros Algoritmos/maskBits @@ -0,0 +1,68 @@ +#include +using namespace std; + +const int lim = 1000000007; + +int dp[2050][105]; +int n; +vector> g; + +void init(){ + for(int i=0;i<2050;i++){ + for(int j=0;j<105;j++){ + dp[i][j] = -1; + } + } +} + +int busca(int mask,int camisa){ + + int size = __builtin_popcount(mask); + if(size == n){ + return 1; + } + if(camisa > 100){ + return 0; + } + if(dp[mask][camisa]!=-1){ + return dp[mask][camisa]; + } + int resp = 0; + for(int i=0;i +using namespace std; +const int maxn = 1000; +int n; +int lista[maxn]; +int lista2[maxn]; +vector g; + +void base(){ + for(int i=0;i= g[b]) a++; + else b--; + soma1 += lista[a]; + a = inicio; b = fim; + soma2 = g[b]; b--; + if(g[a] >= g[b]) a++; + else b--; + soma2 += lista[a]; + lista2[k] = max(soma1,soma2); + k++; + inicio++; + fim++; + } + for(int i=0;i> n; + int z = 1; + int total; + int x1,x2; + while(n!=0){ + g.clear(); + total = 0; + for(int i=0;i> a; + total += a; + g.push_back(a); + } + base(); + x1 = dp(); + x2 = total - x1; + cout << "In game " << z++ << ", the greedy strategy might lose by as many as " << x1 - x2 << " points." << endl; + cin >> n; + } +} diff --git a/Outros Algoritmos/unlocked b/Outros Algoritmos/unlocked new file mode 100644 index 000000000..98c0595d0 --- /dev/null +++ b/Outros Algoritmos/unlocked @@ -0,0 +1,80 @@ +#include +using namespace std; + +const int INF = 10001; +string A,B; +int r; +int validade[10001]; +vector v; +int minimo; +int cost; + +void init(){ + + for(int i=0;i<10000;i++){ + validade[i] = 0; + } +} + +int main(){ + + int inicio,fim; + int z; + z = 1; + cin >> A >> B >> r; + while(A!="0" || B!="0" || r!=0){ + int base; + base = 1000; + inicio = 0; fim = 0; + for(int i=0;i<4;i++){ + inicio += base*(A[i] - 48); + fim += base*(B[i] - 48); + base /= 10; + } + v.clear(); + for(int i=0;i> A; + int base; + int value = 0; + base = 1000; + for(int j=0;j<4;j++){ + value += base*(A[j] - 48); + base /= 10; + } + v.push_back(value); + } + bool ans = false; + init(); + queue> q; + q.push({inicio,0}); + while(!q.empty()){ + pair g; + g = q.front(); q.pop(); + int u,x,point; + point = g.second; + u = g.first; + if(u == fim){ + ans = true; + minimo = point; + break; + } + point++; + for(int i=0;i> A >> B >> r; + } +} diff --git a/README.md b/README.md index 9aa54aa88..73009bba6 100644 --- a/README.md +++ b/README.md @@ -4,29 +4,31 @@ Clean example implementations of data structures and algorithms written in diffe [![Gitter chat](https://badges.gitter.im/VAR-solutions/Algorithms.png)](https://gitter.im/VAR-solutions/Algorithms "Gitter chat") [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT) [![Issues](http://img.shields.io/github/issues/VAR-solutions/Algorithms.svg)](https://github.com/VAR-solutions/Algorithms/issues) -## List of implementations +#### List of implementations [Algorithms list(not updated)](#) -## Contribution +## Contribution! * Contributions are always welcome. Language doesn't matter. Just make sure you're implementing an algorithm. * PRs are welcome. To begin developing, follow the structure: - > Algorithm-Type/algorithm_name/language-name/file_name.extension + > Algorithm-Type/algorithm-name/language-name/file-name.extension e.g - > Sorting/bubble_sort/python/bubble_sort.py + > Sorting/bubble-sort/python/bubble-sort.py - * If there is an implementation of the same algorithm in your language, add your username in front of the file name. + * If there is an implementation of the same algorithm in your language, do not give a PR for that. * Please include a description for the algorithm that you are implementing. It doesn't matter if it's copied from somewhere as long as it helps people that are learning new algorithm. * Graphical examples would be very helpful too. - * Don't forget to include tests. + * You can include tests as well. * Don't remove previous implementations of algorithms. Just add a new file with your own implementation. - * Beautify and cleanup your code for easier reading + * Beautify and clean up your code for easier reading + ### Note: + * If your PR is closed without any comment, it means that your PR does not meet the above criteria. Make sure your PR is **not Duplicate** and it should be **well-documented**. ## Resources - Curated list of resources dealing with algorithms. + The curated list of resources dealing with algorithms. * **Sites** * [Algorithms - Tutorials point](https://www.tutorialspoint.com/data_structures_algorithms/index.htm) @@ -35,9 +37,11 @@ Clean example implementations of data structures and algorithms written in diffe * [Data science - Topcoder](https://www.topcoder.com/community/data-science/data-science-tutorials/) * [Fundamentals Of Algorithms- Geeks For Geeks](http://www.geeksforgeeks.org/fundamentals-of-algorithms/) * [Visual Algorithm - visualising data structures and algorithms through animation](https://visualgo.net/en) + * [Rosetta Code](http://rosettacode.org/wiki/Rosetta_Code) + * [GeeksforGeeks](https://www.geeksforgeeks.org) * **Online classes (Free)** * Coursera - * [Introduction to algorithms Part 1](https://www.coursera.org/learn/introduction-to-algorithms) + * [Introduction to algorithms Part 1](https://www.coursera.org/learn/algorithms-part1) * [Algorithms specialization 4 courses](https://www.coursera.org/specializations/algorithms) * Khan Academy * [Algorithms](https://www.khanacademy.org/computing/computer-science/algorithms) @@ -58,6 +62,8 @@ Clean example implementations of data structures and algorithms written in diffe * [Data Structures](https://www.youtube.com/user/mycodeschool) * [Algorithms and Data Structures Capstone](https://www.edx.org/course/algorithms-data-structures-capstone-uc-san-diegox-algs207x) * [Data Structures and Algorithms](https://www.programiz.com/dsa) + * GeeksForGeeks + * [Algorithms](https://www.geeksforgeeks.org/fundamentals-of-algorithms/) * **Coding Practice Sites** * [HackerRank](https://www.hackerrank.com/) * [HackerEarth](https://www.hackerearth.com/) @@ -71,7 +77,11 @@ Clean example implementations of data structures and algorithms written in diffe * [CodeWars](https://codewars.com/) * [Coderbyte](https://www.coderbyte.com/) * [HireVue](https://www.hirevue.com/) -# Project Maintainers -* [Vishal Gaur](https://github.com/i-vishi):tada:
-* [Ravi Varshney](https://github.com/ravivarshney01):tada:
-* [Ananya Tewari](https://github.com/antew7):tada:
+ * [FreeCodeCamp](https://www.freecodecamp.org/) + * [CodeSignal](https://codesignal.com/) + * [AtCoder](https://atcoder.jp/) + +# Project Maintainers. +* [Vishal Gaur](https://github.com/i-vishi) :tada:
+* [Ravi Varshney](https://github.com/ravivarshney01) :tada:
+* [Ananya Tewari](https://github.com/antew7) :tada:
diff --git a/Random Number/algorithm-random.md b/Random Number/algorithm-random.md new file mode 100644 index 000000000..af7ff4f12 --- /dev/null +++ b/Random Number/algorithm-random.md @@ -0,0 +1,17 @@ +# Random algorithm + + +## Description +Used to generate pseudorandom numbers. +All the versions contained in this folder will generate a variable number of pseudorandom numbers and print them out. + + +## Where and why to use +Use it whenever you need to simulate some random values + +## How +Write the correspondent random function and use it in your code + +## Pseudocode + +random = random() \ No newline at end of file diff --git a/Random Number/guess_number.php b/Random Number/guess_number.php new file mode 100644 index 000000000..c14d471f4 --- /dev/null +++ b/Random Number/guess_number.php @@ -0,0 +1,38 @@ + + + +
+Guess a Number Between 1 and 10: +

+ +Result: + 0) && ($number <11)){ +if ($number != $randomNumber) +{ +echo "Incorrect guess. The correct number was $randomNumber. Try again"; +} +else +{ +echo "$randomNumber is the correct guess. You got it right."; +} +} + +} + +?> +

+

+
diff --git a/Random Number/random.bf b/Random Number/random.bf new file mode 100644 index 000000000..2dfb3bf64 --- /dev/null +++ b/Random Number/random.bf @@ -0,0 +1,36 @@ +temp0[-] +temp1[-] +temp2[-] +temp3[-] +temp4[-] +temp5[-] +randomh[temp0+randomh-] +randoml[temp1+randoml-] +temp3+++++++[temp2+++++++++++@temp3-] +temp2[ + temp0[randomh+temp3+temp0-] + temp3[temp0+temp3-] + temp1[randomh+temp3+temp4+temp1-] + temp4[temp1+temp4-] + temp3[ + randoml+[temp4+temp5+randoml-] + temp5[randoml+temp5-]+ + temp4[temp5-temp4[-]] + temp5[randomh+temp5-] + temp3-] +temp2-] +++++++[temp3++++++++temp2-] +temp3-[ + temp1[randomh+temp2+temp1-] + temp2[temp1+temp2-] +temp3-] +temp0[-]temp1[-]+++++[temp0+++++temp1-] +temp0[ + randoml+[temp1+temp2+randoml-] + temp2[randoml+temp2-]+ + temp1[temp2-temp1[-]] + temp2[randomh+temp2-] +temp0-] +++++++[randomh+++++++++temp0-] +randomh[x+temp0+randomh-] +temp0[randomh+temp0-] diff --git a/Random Number/random.c b/Random Number/random.c new file mode 100644 index 000000000..9a9b3062a --- /dev/null +++ b/Random Number/random.c @@ -0,0 +1,14 @@ +// C program to generate random numbers +#include +#include + +// Driver program and testing +int main(void) +{ + // This program will create same sequence of + // random numbers on every program run + + for(int i = 0; i<5; i++) + printf(" %d ", rand()); + return 0; +} diff --git a/Random Number/random.cpp b/Random Number/random.cpp new file mode 100644 index 000000000..6ebc69e67 --- /dev/null +++ b/Random Number/random.cpp @@ -0,0 +1,11 @@ +#include + +int main (int argc, char const* argv[]) +{ + srand((unsigned)time(0)); + int u = 100; + int d = 30; + int r = rand()%(u-d+1) + d; + std::cout << "Random Number = " << r << std::endl; + return 0; +} diff --git a/Random Number/random.cs b/Random Number/random.cs new file mode 100644 index 000000000..9d9f9b583 --- /dev/null +++ b/Random Number/random.cs @@ -0,0 +1,25 @@ +using System; + +namespace RandomNumber +{ + class Program + { + static void Main(string[] args) + { + Random random = new Random(); + + // Generate Random Number + int num = random.Next(); + + // Generate Number < 1000 + int numLess1000 = random.Next(1000); + + // Generate Number between a MIN & MAX Value + int numMinMax = random.Next(10, 99); + + Console.WriteLine($" Random Number: {num} \n Less than 1000: {numLess1000} \n Min Max: {numMinMax} "); + + Console.ReadLine(); + } + } +} diff --git a/Random Number/random.go b/Random Number/random.go new file mode 100644 index 000000000..fe85e2afc --- /dev/null +++ b/Random Number/random.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "math/rand" + "time" +) + +func main() { + rand.Seed(time.Now().UnixNano()) + for i := 0; i < 10; i++ { + fmt.Println(rand.Intn(100)) + } +} diff --git a/Random Number/random.html b/Random Number/random.html new file mode 100644 index 000000000..ed65f5957 --- /dev/null +++ b/Random Number/random.html @@ -0,0 +1,16 @@ + + + Random Number + + + +

NUMERO

+ + + + + diff --git a/Random Number/random.java b/Random Number/random.java new file mode 100644 index 000000000..d5f8663eb --- /dev/null +++ b/Random Number/random.java @@ -0,0 +1,28 @@ +// A Java program to demonstrate random number generation +// using java.util.Random; +import java.util.Random; + +public class generateRandom{ + + public static void main(String args[]) + { + // create instance of Random class + Random rand = new Random(); + + // Generate random integers in range 0 to 999 + int rand_int1 = rand.nextInt(1000); + int rand_int2 = rand.nextInt(1000); + + // Print random integers + System.out.println("Random Integers: "+rand_int1); + System.out.println("Random Integers: "+rand_int2); + + // Generate Random doubles + double rand_dub1 = rand.nextDouble(); + double rand_dub2 = rand.nextDouble(); + + // Print random doubles + System.out.println("Random Doubles: "+rand_dub1); + System.out.println("Random Doubles: "+rand_dub2); + } +} diff --git a/Random Number/random.js b/Random Number/random.js index bbe412a02..ae0a0b97c 100644 --- a/Random Number/random.js +++ b/Random Number/random.js @@ -1,9 +1,13 @@ //La función genera un número aleatorio entre 1 y el número deseado +var number=5; +var A = []; +function getRandomInt(min,max){ + return Math.floor(Math.random() * (max - min + 1)) + min; +} -function numRandom (num) { - - return Math.floor((Math.random() * num) + 1); - +for (i = 0; i < number; i++){ + A[i] = getRandomInt(1,30); + console.log(A[i]); } -console.log(numRandom(5); + diff --git a/Random Number/random.kt b/Random Number/random.kt new file mode 100644 index 000000000..cdff0a1dd --- /dev/null +++ b/Random Number/random.kt @@ -0,0 +1,7 @@ +import java.util.* + +fun main(args: Array) { + val rand = Random() + println(rand.nextInt()) + println(rand.nextDouble()) +} \ No newline at end of file diff --git a/Random Number/random.py b/Random Number/random.py new file mode 100644 index 000000000..f1f7ddd70 --- /dev/null +++ b/Random Number/random.py @@ -0,0 +1,7 @@ +#Way to generate random numbers in python +# random.randint(l,r+1) will generate a random number between l and r + + +import random +for x in range(10): + print random.randint(1,101) diff --git a/Random Number/random.rb b/Random Number/random.rb new file mode 100644 index 000000000..8bc0299aa --- /dev/null +++ b/Random Number/random.rb @@ -0,0 +1,7 @@ +require 'securerandom' +i = 0 +while i < 5 do + randomNum = SecureRandom.random_number(100) + p randomNum + i = i+1 + end diff --git a/Random Number/secure_random.java b/Random Number/secure_random.java new file mode 100644 index 000000000..ccf8b5bbf --- /dev/null +++ b/Random Number/secure_random.java @@ -0,0 +1,36 @@ +import java.security.SecureRandom; +/** + * A Java program to generate a random number with java.security.SecureRandom + * which is harder to predict than a number generated with java.util.Random. + * + * This is because java.util.Random uses the system clock as its seed and this can be + * reproduced more easily. On the other hand java.security.SecureRandom takes random + * data from your os and uses that as its seed. This makes it hard to predict the randomly + * generated number. + * + * In programs where high security is mandatory, you might consider using java.util.SecureRandom. + */ +public class generateSecureRandom { + + public static void main(String[] args) { + // create instance of SecureRandom class + SecureRandom secureRand = new SecureRandom(); + + // Generate random integers in range 0 to 999 + int secureRand_int1 = secureRand.nextInt(1000); + int secureRand_int2 = secureRand.nextInt(1000); + + // Print random integers + System.out.println("Random Integers: " + secureRand_int1); + System.out.println("Random Integers: " + secureRand_int2); + + // Generate Random doubles + double rand_dub1 = secureRand.nextDouble(); + double rand_dub2 = secureRand.nextDouble(); + + // Print random doubles + System.out.println("Random Doubles: " + rand_dub1); + System.out.println("Random Doubles: " + rand_dub2); + } + +} diff --git a/Recursive Algorithms/Factorial.c b/Recursive Algorithms/Factorial.c new file mode 100644 index 000000000..e117d6167 --- /dev/null +++ b/Recursive Algorithms/Factorial.c @@ -0,0 +1,19 @@ +#include +long int multiplyNumbers(int n); + +int main() +{ + int n; + printf("Enter a positive integer: "); + scanf("%d", &n); + printf("Factorial of %d = %ld", n, multiplyNumbers(n)); + return 0; +} +long int multiplyNumbers(int n) +{ + if (n >= 1) + return n*multiplyNumbers(n-1); + else + return 1; +} +} diff --git a/Recursive Algorithms/Factorial/Java/factorial.java b/Recursive Algorithms/Factorial/Java/factorial.java new file mode 100644 index 000000000..82e440532 --- /dev/null +++ b/Recursive Algorithms/Factorial/Java/factorial.java @@ -0,0 +1,34 @@ +import java.util.Scanner; + + +public class Factorial { + + static int findFactorial( Integer number ) + { + if( number == 0 ) + return 1; + else if( number==1 ) + return 1; + + return number*findFactorial(number-1); + } + + public static void main(String[] args) { + + System.out.println("Enter the number for Factoial"); + Scanner read = new Scanner(System.in); + String input = read.nextLine(); + + //Ensuring that the input is only a number + while ( ! input.matches("[0-9]+") ) + { + System.out.println("Enter a valid number"); + input = read.nextLine(); + } + Integer number=Integer.parseInt(input); + Integer factorial = findFactorial(number); + System.out.println("Factorial of " + number + " is " + factorial); + + } + +} diff --git a/Recursive Algorithms/Factorial/Python/factorial.py b/Recursive Algorithms/Factorial/Python/factorial.py new file mode 100644 index 000000000..4e95f3fe2 --- /dev/null +++ b/Recursive Algorithms/Factorial/Python/factorial.py @@ -0,0 +1,5 @@ +def factorial(n): + if n == 1: + return n + else: + return n*factorial(n-1) diff --git a/Recursive Algorithms/Factorial/kotlin/Factorial.kt b/Recursive Algorithms/Factorial/kotlin/Factorial.kt new file mode 100644 index 000000000..a9f645f5b --- /dev/null +++ b/Recursive Algorithms/Factorial/kotlin/Factorial.kt @@ -0,0 +1,4 @@ +fun factorial(n: Int): Int { + return if (n == 1) n + else n * factorial(n - 1) +} diff --git a/Recursive Algorithms/Fibonacci/Java/fibonacci.java b/Recursive Algorithms/Fibonacci/Java/fibonacci.java new file mode 100644 index 000000000..1bf1a7ec6 --- /dev/null +++ b/Recursive Algorithms/Fibonacci/Java/fibonacci.java @@ -0,0 +1,40 @@ +import java.util.*; +import java.math.*; + +class fibonacci +{ + public static void main(String[] args) + { + Scanner sc = new Scanner(System.in); + + // Getting input from system. + BigInteger n = new BigInteger(sc.nextLine(), 10); + + // Base cases + if(n.toString(10).equals("0")) + { + System.out.println(0); + return; + } + else if(n.toString(10).equals("1")) + { + System.out.println(1); + return; + } + + // Initialization of base numbers for n>=2 + BigInteger a = new BigInteger("0", 10); + BigInteger b = new BigInteger("1", 10); + BigInteger i = new BigInteger("2", 10); + + // main loop to get the nth fibonacci number + while(i.compareTo(n) == -1 || i.compareTo(n) == 0) + { + BigInteger c = a.add(b); + a = b; + b = c; + i = i.add(new BigInteger("1",10)); + } + System.out.println(b.toString(10)); + } +} diff --git a/Recursive Algorithms/Fibonacci/Java/fibonacciModM.java b/Recursive Algorithms/Fibonacci/Java/fibonacciModM.java new file mode 100644 index 000000000..c8582e2df --- /dev/null +++ b/Recursive Algorithms/Fibonacci/Java/fibonacciModM.java @@ -0,0 +1,57 @@ +// This code is the generalized form for fibonacci number: Question : find the nth Fibonacci number and find (fn)%m. + +import java.util.*; +import java.math.*; + +class sumOfNFibonacci +{ + + // Finding the pisano series for number m. + public static int getPisanoNumber(int m) + { + long a = 0; + long b = 1; + int i; + for(i=0;i +typedef struct Range { + int start, end, sum; +} Range; + +Range maxSubseq(const int sequence[], const int len) { + int maxSum = 0, thisSum = 0, i = 0; + int start = 0, end = -1, j; + + for (j = 0; j < len; j++) { + thisSum += sequence[j]; + if (thisSum < 0) { + i = j + 1; + thisSum = 0; + } else if (thisSum > maxSum) { + maxSum = thisSum; + start = i; + end = j; + } + } + + Range r; + if (start <= end && start >= 0 && end >= 0) { + r.start = start; + r.end = end + 1; + r.sum = maxSum; + } else { + r.start = 0; + r.end = 0; + r.sum = 0; + } + return r; +} + +int main(int argc, char **argv) { + int a[] = {-1 , -2 , 3 , 5 , 6 , -2 , -1 , 4 , -4 , 2 , -1}; + int alength = sizeof(a)/sizeof(a[0]); + + Range r = maxSubseq(a, alength); + printf("Max sum = %d\n", r.sum); + int i; + for (i = r.start; i < r.end; i++) + printf("%d ", a[i]); + printf("\n"); + + return 0; +} diff --git a/Recursive Algorithms/PrintPemutations.java b/Recursive Algorithms/PrintPemutations.java new file mode 100644 index 000000000..fdb4d2e58 --- /dev/null +++ b/Recursive Algorithms/PrintPemutations.java @@ -0,0 +1,92 @@ +package Recursioncontd; + +public class PrintPemutations { + + public static void main(String[] args) { + String s = "abc"; + PrintPermutations2(s, ""); + StringBuilder s1 = new StringBuilder("abc"); + StringBuilder s2 = new StringBuilder(); + //PrintPermutations1SB(s1, s2); + //PrintPermutations1SB(s1, s2); + + } + +public static void PrintPermutations2(String str, String asf) { + + if(str.length()==0) { + System.out.println(asf); + return; + } + char ch = str.charAt(0); + String roq = str.substring(1); + for(int i=0; i<=asf.length(); i++) { + String l = asf.substring(0, i); + String r = asf.substring(i); + PrintPermutations2(roq, r+ch+l); + } + + } + + public static void PrintPermutations1(String str, String asf) { + + if(str.length()==0) { + System.out.println(asf); + return; + } + + for(int i=0; i +using namespace std; + +int sumOfDigits(int n){ + if(n == 0) return 0; + + return n%10+sumOfDigits(n/10); +} + +int main() +{ + int n=1729; + cout << "Sum of Digits of " << n << " is " << sumOfDigits(n) << endl; + return 0; +} diff --git a/Recursive Algorithms/Tower of Hanoi/Java/TOH.java b/Recursive Algorithms/Tower of Hanoi/Java/TOH.java new file mode 100644 index 000000000..0359e3514 --- /dev/null +++ b/Recursive Algorithms/Tower of Hanoi/Java/TOH.java @@ -0,0 +1,23 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +class TOH { + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + int n = Integer.parseInt(br.readLine()); + towerOfHanoi(n, 'A', 'C', 'B'); + } + + static void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod) + { + if (n == 1) + { + System.out.println("Move disk 1 from rod " + from_rod + " to rod " + to_rod); + return; + } + towerOfHanoi(n-1, from_rod, aux_rod, to_rod); + System.out.println("Move disk " + n + " from rod " + from_rod + " to rod " + to_rod); + towerOfHanoi(n-1, aux_rod, to_rod, from_rod); + } +} diff --git a/Recursive Algorithms/josephus.cpp b/Recursive Algorithms/josephus.cpp new file mode 100644 index 000000000..ad15ead71 --- /dev/null +++ b/Recursive Algorithms/josephus.cpp @@ -0,0 +1,34 @@ +#include +#include + +using namespace std; + +/** + * Algoritmo recursivo de Flavious Josephus + * @author: Mateus Tranquilino + * */ + +/** + * Calcula o sobrevivente no problema de Flavious Josephus + * em um circulo de N pessoas e de salto K. + * */ +int josephus(int n, int k){ + if(n==1) return 1; + return ( ( ( josephus(n-1, k) + k-1) % n ) + 1); +} + +int main(){ + unsigned int n, k; + int x; + printf("Quantos casos de Testes? "); + scanf("%d", &x); + + for (int i=0; i < x; i++){ + printf("O número de pessoas no circulo "); + scanf("%d", &n); + printf("O tamanho do salto "); + scanf("%d", &k); + printf("No caso %d a pessoa na posição %d termina viva\n", i+1, josephus(n,k)); + cout << endl; + } +} diff --git a/Recursive Algorithms/minimax/tic-tac-toe/tictactoe.py b/Recursive Algorithms/minimax/tic-tac-toe/tictactoe.py new file mode 100644 index 000000000..b694ca5aa --- /dev/null +++ b/Recursive Algorithms/minimax/tic-tac-toe/tictactoe.py @@ -0,0 +1,210 @@ +import time +import random + + +class TicTacToe(): + '''Class that has all necesarry components for a tic tac toe game''' + def __init__(self, player1, player2): + self.board = [[None, None, None], + [None, None, None], + [None, None, None]] + self.current_player = player1.player_mark + self.player1 = player1 + self.player2 = player2 + + def render(self): + '''Renders the current board state''' + for row in self.board: + print("|", end="") + for item in row: + if item is None: + print(".", end="|") + else: + print(item, end="|") + print() + + def possible_moves(self): + '''Finds all possible_moves of current board state''' + moves = [] + for x in range(len(self.board)): + for y in range(len(self.board[x])): + if self.board[x][y] is None: + moves.append((x, y)) + + return moves + + def legal_move(self, move): + '''Determines if given move is legal''' + legal_moves = self.possible_moves() + if move in legal_moves: + return True + return False + + def move(self, move): + '''Moves a piece and switches current_player''' + if self.legal_move(move): + move_x = move[0] + move_y = move[1] + self.board[move_x][move_y] = self.current_player + self.last_move = move + self.switch() + return True + else: + return False + + def switch(self): + '''Switches current player''' + if self.current_player == "x": + self.current_player = "o" + else: + self.current_player = "x" + + def game_over(self): + '''Finds if current board_state is full and the game is over''' + if self.game_won(): + return True + for row in self.board: + for item in row: + if item is None: + return False + return True + + def game_won(self): + '''Finds if game is won and updates self.winning_player''' + board = self.board + for x in range(len(self.board)): + for y in range(len(self.board[x])): + mark = self.board[x][y] + if board[x][y] is not None: + if board[0][y] == board[1][y] == board[2][y]: + self.winning_player = mark + return True + if board[x][0] == board[x][1] == board[x][2]: + self.winning_player = mark + return True + if x == y and board[0][0] == board[1][1] == board[2][2]: + self.winning_player = mark + return True + if x + y == 2: + if board[0][2] == board[1][1] == board[2][0]: + self.winning_player = mark + return True + return False + + def revert_move(self, move): + x = move[0] + y = move[1] + self.switch() + self.board[x][y] = None + + def play(self): + + while not self.game_over(): + player_1_move = self.player1.best_move(self) + time.sleep(1) + self.move(player_1_move) + self.render() + print() + + if self.game_over(): + if self.game_won(): + print(self.winning_player, "has won!") + exit(0) + print("Nobody has won") + exit(0) + + player_2_move = self.player2.best_move(self) + time.sleep(1) + self.move(player_2_move) + self.render() + print() + + if self.game_won(): + print(self.winning_player, "has won!") + exit(0) + else: + print("Nobody has won.") + + +class MiniMaxPlayer(): + '''A perfect player that uses minimax to determine best move''' + def __init__(self, player): + self.player_mark = player + + def score(self, game, depth): + '''returns score of given board''' + if game.game_won(): + if game.winning_player is self.player_mark: + return 10 - depth + else: + return depth - 10 + return 0 + + def minimax(self, game, depth): + '''Minimax solution to selecting what to play''' + if game.game_over(): + return self.score(game, depth) + + depth += 1 + + scores = [] + moves = [] + # Recursively adds all scores of every possible move of a given state + for move in game.possible_moves(): + game.move(move) + scores.append(self.minimax(game, depth)) + game.revert_move(move) + moves.append(move) + + self.scores = scores + self.moves = moves + + # max solution in case current player is this player + if game.current_player is self.player_mark: + max_score_idx = scores.index(max(scores)) + highest_score = scores[max_score_idx] + # finds all moves with same value and selects one at random so + # every game doesn't play out the same + best_moves = [] + for i, move in enumerate(moves): + if scores[i] == highest_score: + best_moves.append(move) + self.choice = (random.choice(best_moves)) + return scores[max_score_idx] + + # min solution in case current player is opponent + else: + min_score_idx = scores.index(min(scores)) + self.choice = moves[min_score_idx] + return scores[min_score_idx] + + def best_move(self, game): + '''returns best move calculated with mini-max''' + self.minimax(game, 0) + return self.choice + + +class HumanPlayer(): + def __init__(self, player): + self.player_mark = player + + def best_move(self, game): + possible_moves = game.possible_moves() + x = None + y = None + while True: + x = int(input("What row do you want to mark?: ")) - 1 + y = int(input("What column do you want to mark?: ")) - 1 + if (x, y) in possible_moves: + break + else: + print("That position has already been marked") + return (x, y) + + +# player1 starts, indepent of marks. +player1 = HumanPlayer("x") +player2 = MiniMaxPlayer("o") + +game = TicTacToe(player1, player2) +game.play() \ No newline at end of file diff --git a/Scheduling/FCFS/fcfs.cpp b/Scheduling/FCFS/fcfs.cpp new file mode 100644 index 000000000..a3f99fbbf --- /dev/null +++ b/Scheduling/FCFS/fcfs.cpp @@ -0,0 +1,163 @@ +<<<<<<< HEAD +//First Comes First Serve(FCFS) + +#include + +using namespace std; + +void Sort_by_arrival_time(int arrival_time[], int burst_time[], int n){ + vector< pair > v; + + for (int i = 0; i < n; ++i){ + v.push_back({arrival_time[i], burst_time[i]}); + } + + sort(v.begin(), v.end()); + + for (int i = 0; i < n; ++i) + { + arrival_time[i] = v[i].first; + burst_time[i] = v[i].second; + } +} + +void findWaitingTime(int processes[], int n, int bt[], int wt[]) { + + wt[0] = 0; + for (int i = 1; i < n ; i++ ) + wt[i] = bt[i-1] + wt[i-1] ; +} + +void findTurnAroundTime( int processes[], int n, int bt[], int wt[], int tat[]) { + for (int i = 0; i < n ; i++) + tat[i] = bt[i] + wt[i]; +} + +void findavgTime( int processes[], int n, int bt[]) { + int wt[n], tat[n], total_wt = 0, total_tat = 0; + + findWaitingTime(processes, n, bt, wt); + + findTurnAroundTime(processes, n, bt, wt, tat); + + cout << "Processes "<< " Burst time " + << " Waiting time " << " Turn around time\n"; + for (int i=0; i + +using namespace std; + +void Sort_by_arrival_time(int arrival_time[], int burst_time[], int n){ + vector< pair > v; + + for (int i = 0; i < n; ++i){ + v.push_back({arrival_time[i], burst_time[i]}); + } + + sort(v.begin(), v.end()); + + for (int i = 0; i < n; ++i) + { + arrival_time[i] = v[i].first; + burst_time[i] = v[i].second; + } +} + +void findWaitingTime(int processes[], int n, int bt[], int wt[]) { + + wt[0] = 0; + for (int i = 1; i < n ; i++ ) + wt[i] = bt[i-1] + wt[i-1] ; +} + +void findTurnAroundTime( int processes[], int n, int bt[], int wt[], int tat[]) { + for (int i = 0; i < n ; i++) + tat[i] = bt[i] + wt[i]; +} + +void findavgTime( int processes[], int n, int bt[]) { + int wt[n], tat[n], total_wt = 0, total_tat = 0; + + findWaitingTime(processes, n, bt, wt); + + findTurnAroundTime(processes, n, bt, wt, tat); + + cout << "Processes "<< " Burst time " + << " Waiting time " << " Turn around time\n"; + for (int i=0; i>>>>>> 2db113523ebbfb33ba57baa4f18f9baa62be7c49 diff --git a/Scheduling/sjf.cpp b/Scheduling/sjf.cpp new file mode 100644 index 000000000..13d897fde --- /dev/null +++ b/Scheduling/sjf.cpp @@ -0,0 +1,67 @@ +#include + +using namespace std; +int main() { + int n; + cin >> n; + + int p[n], at[n], bt[n], wt[n], tat[n], twt = 0, ttat = 0; + + for (int i = 0; i < n; ++i) { + cin >> p[i] >> at[i] >> bt[i]; + } + + int rt[n]; + for (int i = 0; i < n; i++) + rt[i] = bt[i]; + + int complete = 0, t = 0, minm = INT_MAX; + int shortest = 0, finish_time; + bool check = false; + + while (complete != n) { + + for (int j = 0; j < n; j++) { + + if ((at[j] <= t) && (rt[j] < minm) && rt[j] > 0) { + minm = rt[j]; + shortest = j; + check = true; + + } + + } + if (check == false) { + t++; + continue; + } + rt[shortest]--; + minm = rt[shortest]; + if (minm == 0) + minm = INT_MAX; + + if (rt[shortest] == 0) { + complete++; + check = false; + finish_time = t + 1; + + wt[shortest] = finish_time - bt[shortest] - at[shortest]; + if (wt[shortest] < 0) + wt[shortest] = 0; + } + t++; + } + for (int i = 0; i < n; i++) + tat[i] = bt[i] + wt[i]; + cout << "Processes " <<" Burst time " <<" Waiting time " << " Turn around time\n"; + for (int i = 0; i < n; i++) { + twt = twt + wt[i]; + ttat = ttat + tat[i]; + cout << " " << p[i] << "\t\t" < + +int min(int x, int y) { return (x<=y)? x : y; } + +int fibMonaccianSearch(int arr[], int x, int n) +{ + int fibMMm2 = 0; + int fibMMm1 = 1; + int fibM = fibMMm2 + fibMMm1; + + while (fibM < n) + { + fibMMm2 = fibMMm1; + fibMMm1 = fibM; + fibM = fibMMm2 + fibMMm1; + } + + + int offset = -1; + + + while (fibM > 1) + { + + int i = min(offset+fibMMm2, n-1); + + + if (arr[i] < x) + { + fibM = fibMMm1; + fibMMm1 = fibMMm2; + fibMMm2 = fibM - fibMMm1; + offset = i; + } + + else if (arr[i] > x) + { + fibM = fibMMm2; + fibMMm1 = fibMMm1 - fibMMm2; + fibMMm2 = fibM - fibMMm1; + } + + + else return i; + } + + if(fibMMm1 && arr[offset+1]==x)return offset+1; + + + return -1; +} + + +int main(void) +{ + int arr[] = {10, 22, 35, 40, 45, 50, 80, 82, + 85, 90, 100}; + int n = sizeof(arr)/sizeof(arr[0]); + int x = 85; + printf("Found at index: %d", + fibMonaccianSearch(arr, x, n)); + return 0; +} diff --git a/Searching/Interpolation Search/js/interpolation_search.js b/Searching/Interpolation Search/js/interpolation_search.js new file mode 100644 index 000000000..cdb2794b4 --- /dev/null +++ b/Searching/Interpolation Search/js/interpolation_search.js @@ -0,0 +1,31 @@ +function interpolation(array, match) { + var c = [], mid, i = 0 , f = array.length - 1; + + while (match > array[i] && match <= array[f]) { + c.push({ + "i": i, + "f": f, + "comparison": match + " > " + array[i] + " && " + match + " <= " + array[f] + "?" + }); + + mid = Math.floor(i + ((match - array[i])/(array[f] - array[i])) * (f - i)); + + if (match > array[mid]) { + i = mid + 1; + } else if (match < array[mid]) { + f = mid - 1; + } else { + i = mid + } + } + c.push({ + "i": i, + "f": f, + "comparison": match + " > " + array[i] + " && " + match + " <= " + array[f] + "?" + }); + + return { + comparisons: c, + result: (array[i] == match)? i: -1 + }; +} diff --git a/Searching/Jump Search/go/src/main.go b/Searching/Jump Search/go/src/main.go new file mode 100644 index 000000000..655a3d0a8 --- /dev/null +++ b/Searching/Jump Search/go/src/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "sort" + "math" + "fmt" +) + +func jump_search(arr []int, x int) int{ + length := float64(len(arr)) + step := math.Sqrt(length) + + prev := 0 + for arr[int(math.Min(step, length) - 1)] < x { + prev = int(step) + step = step + math.Sqrt(length) + if prev >= int(length) { + return -1 + } + } + + for arr[int(prev)] < x { + prev = prev + 1 + if prev == int(math.Min(step, length)) { + return -1 + } + } + + if arr[int(prev)] == x { + return prev + } + + return -1 +} + +func main() { + length := 0 + x := 0 + fmt.Println("Enter the length of array") + fmt.Scanln(&length) + fmt.Println("Enter elements of array") + array := make([]int, length) + for i := 0; i < length; i++ { + fmt.Scanln(&array[i]) + } + fmt.Printf("Your array : %v \n", array) + sort.Ints(array) + fmt.Printf("Your sorted array : %v \n", array) + fmt.Println("Enter elements you looking for") + fmt.Scanln(&x) + result := jump_search(array, x) + fmt.Printf("%v is in array index %v", x, result) +} \ No newline at end of file diff --git a/Searching/Linear Search/LinearSearch(C).c b/Searching/Linear Search/LinearSearch(C).c new file mode 100644 index 000000000..931c917d3 --- /dev/null +++ b/Searching/Linear Search/LinearSearch(C).c @@ -0,0 +1,30 @@ +#include +#include + +int main() +{ + int numb,i,x; + printf("Enter the array value:"); + scanf("%d",&x); + int arr[x]; + printf("Enter the Integer numbers to the array..\n"); + for(i=0;i<=(x-1);i++) + { + printf("Enter the %d number:",i+1); + scanf("%d",&arr[i]); + } + printf("Enter a Integer Value to search:"); + scanf("%d",&numb); + for(i=0;i<=(x-1);i++) + { + if (arr[i]==numb) + { + printf("%d is at the %d point of the array.",numb,i+1); + break; + } + if (i==(x-1)) + printf("The Value you entered is not at the array.."); + } + + return 0; +} diff --git a/Searching/Linear Search/LinearSearchRec.java b/Searching/Linear Search/LinearSearchRec.java new file mode 100644 index 000000000..779b2fbf9 --- /dev/null +++ b/Searching/Linear Search/LinearSearchRec.java @@ -0,0 +1,21 @@ + +// Java code for linearly search x in arr[]. If x +// is present then return its location, otherwise +// return -1 +class LinearSearch +{ + // This function returns index of element x in arr[] + static int search(int arr[], int n, int x) + { + for (int i = 0; i < n; i++) + { + // Return the index of the element if the element + // is found + if (arr[i] == x) + return i; + } + + // return -1 if the element is not found + return -1; + } +} \ No newline at end of file diff --git a/Searching/Linear Search/Linearsearch.kt b/Searching/Linear Search/Linearsearch.kt new file mode 100644 index 000000000..ad43856c3 --- /dev/null +++ b/Searching/Linear Search/Linearsearch.kt @@ -0,0 +1,15 @@ +fun >linearSearch(list:List, key:T):Int?{ + for ((index, value) in list.withIndex()) { + if (value == key) return index + } + return null +} + +fun main(args: Array) { + println("\nOrdered list:") + val ordered = listOf("nik", "ruddof", "alisa", "shashi", "varun") + println(ordered) + val name = "shashi" + val position = linearSearch(ordered, name) + println("\n${name} is in the position ${position} in the ordered List.") +} diff --git a/Searching/Linear Search/go/linear_search.go b/Searching/Linear Search/go/linear_search.go new file mode 100644 index 000000000..34894c253 --- /dev/null +++ b/Searching/Linear Search/go/linear_search.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "strconv" +) + +func main() { + array := []int32{23, 42, 65, 75, 92, 75, 21, 56, 32, 93} + status := search(array, 42) + fmt.Println(status) +} + +func search(array []int32, target int32) string { + for i := range array { + if array[i] == target { + return "found at " + strconv.Itoa(i) + } + } + return "not found" +} diff --git a/Searching/Linear Search/java/linearSearch.java b/Searching/Linear Search/java/linearSearch.java new file mode 100644 index 000000000..e847e3c8a --- /dev/null +++ b/Searching/Linear Search/java/linearSearch.java @@ -0,0 +1,17 @@ +class LinearSearch +{ + // This function returns index of element x in arr[] + static int search(int arr[], int n, int x) + { + for (int i = 0; i < n; i++) + { + // Return the index of the element if the element + // is found + if (arr[i] == x) + return i; + } + + // return -1 if the element is not found + return -1; + } +} \ No newline at end of file diff --git a/Searching/Linear Search/linearSearch.java b/Searching/Linear Search/linearSearch.java new file mode 100644 index 000000000..cc0e4d84f --- /dev/null +++ b/Searching/Linear Search/linearSearch.java @@ -0,0 +1,26 @@ +import java.util.*; +import java.io.*; + +public class linearSearch { + + public static void main(String args[]) { + int[] arr = new int[100]; + int n,element; + Scanner s = new Scanner(System.in); + System.out.println("Enter size of array"); + n = s.nextInt(); + System.out.println("Enter elements of array"); + for(int i=0;i, value : i32) -> i32{ + for (i, &j ) in v.iter().enumerate() { + if j == value{ + return i as i32; + } + } + return i32::MAX; +} + + +fn main() { + println!("Hello, world!"); + let v : Vec = vec![1,2,3,4,5,9,0]; + let index = linear_search(&v, 4); + if index != i32::MAX{ + println!("index of element is -> {}", index); + } + else { + println!("Element not found"); + } +} diff --git a/Searching/bayer-moore-algorithm/boyer_moore_algorithm.js b/Searching/bayer-moore-algorithm/boyer_moore_algorithm.js new file mode 100644 index 000000000..67bb4133f --- /dev/null +++ b/Searching/bayer-moore-algorithm/boyer_moore_algorithm.js @@ -0,0 +1,21 @@ +export const search = (string, pattern) => { + const mainString = string.split(''); + pattern = pattern.split(''); + let i = 0, j; + while (i < mainString.length) { + for (j = pattern.length - 1; j >= 0; j--) { + if (i + j >= mainString.length) return null; + if (mainString[i + j] !== pattern[j]) break; + } + if (j > 0) { + let k = j; + do { + k--; + } while (k > 0 && mainString[i + j] !== pattern[k]); + i += j - k; + } + else { + return i; + } + } +}; diff --git a/Searching/binary search/BinarySearch.kt b/Searching/binary search/BinarySearch.kt new file mode 100644 index 000000000..235236811 --- /dev/null +++ b/Searching/binary search/BinarySearch.kt @@ -0,0 +1,15 @@ +fun > binarySearch(list: List, key: T): Int? { + var rangeStart = 0 + var rangeEnd = list.count() + while (rangeStart < rangeEnd) { + val midIndex = rangeStart + (rangeEnd - rangeStart)/2 + if (list[midIndex] == key) { + return midIndex + } else if (list[midIndex] < key) { + rangeStart = midIndex + 1 + } else { + rangeEnd = midIndex + } + } + return null +} diff --git a/Searching/binary search/JavaScript/binarySearch.js b/Searching/binary search/JavaScript/binarySearch.js new file mode 100644 index 000000000..c5918cace --- /dev/null +++ b/Searching/binary search/JavaScript/binarySearch.js @@ -0,0 +1,35 @@ +const innerBinarySearch = (arr, key, from, to) => { + if (from > to) { + return -1; + } + + const middleIndex = Math.trunc((from + to) / 2); + + if (arr[middleIndex] > key) { + return innerBinarySearch(arr, key, from, middleIndex - 1); + } else if (arr[middleIndex] < key) { + return innerBinarySearch(arr, key, middleIndex + 1, to); + } + + return middleIndex; +}; + +const iterativeBinarySearch = (arr, key) => { + let start = 0; + let end = arr.length - 1; + let indexToReturn = -1; + + while (start <= end) { + const middleIndex = ((start + end) / 2) | 0; + if (arr[middleIndex] < key) { + start = middleIndex + 1; + } else if (arr[middleIndex] > key) { + end = middleIndex - 1; + } else { + indexToReturn = middleIndex; + break; + } + } + + return indexToReturn; +}; \ No newline at end of file diff --git a/Searching/binary search/Ruby/binSearch.rb b/Searching/binary search/Ruby/binSearch.rb new file mode 100644 index 000000000..dcfc1462a --- /dev/null +++ b/Searching/binary search/Ruby/binSearch.rb @@ -0,0 +1,19 @@ + def binary_search(a, n, x) + index_start = 0 + index_end = n - 1 + + while index_start <= index_end do + index_middle = (index_start + index_end) / 2 + if a[index_middle] == x + return index_middle + elsif x < a[index_middle] + index_end = index_middle - 1 + else + index_start = index_middle + 1 + end + end + return "not found" +end + +a = [1, 2, 3, 4, 5, 7] +puts binary_search(a, a.size, 3) diff --git a/Searching/binary search/c/BS.c b/Searching/binary search/c/BS.c new file mode 100644 index 000000000..9e76d78da --- /dev/null +++ b/Searching/binary search/c/BS.c @@ -0,0 +1,44 @@ + +// C program to implement recursive Binary Search +#include + +// A recursive binary search function. It returns +// location of x in given array arr[l..r] is present, +// otherwise -1 +int binarySearch(int arr[], int l, int r, int x) +{ + if (r >= l) + { + int mid = l + (r - l)/2; + + // If the element is present at the middle + // itself + if (arr[mid] == x) + return mid; + + // If element is smaller than mid, then + // it can only be present in left subarray + if (arr[mid] > x) + return binarySearch(arr, l, mid-1, x); + + // Else the element can only be present + // in right subarray + return binarySearch(arr, mid+1, r, x); + } + + // We reach here when element is not + // present in array + return -1; +} + +int main(void) +{ + int arr[] = {2, 3, 4, 10, 40}; + int n = sizeof(arr)/ sizeof(arr[0]); + int x = 10; + int result = binarySearch(arr, 0, n-1, x); + (result == -1)? printf("Element is not present in array") + : printf("Element is present at index %d", + result); + return 0; +} \ No newline at end of file diff --git a/Searching/binary search/c/Makefile b/Searching/binary search/c/Makefile new file mode 100644 index 000000000..b1d9b640a --- /dev/null +++ b/Searching/binary search/c/Makefile @@ -0,0 +1,12 @@ +CC=g++ +CCFLAGS= -Wno-deprecated -Wall -g -std=c++11 +TEST_DIR=./test +TEST_BUILD_DIR=./build/test +TEST_OBJ=test/*.cc +TEST_IDIR=-I./ +SOURCE_FILES=*.c + +unit_test: $(TEST_OBJ) + mkdir -p $(TEST_BUILD_DIR) + $(CC) $(CCFLAGS) $(SOURCE_FILES) -o $(TEST_BUILD_DIR)/$@ $^ $(TEST_IDIR) + $(TEST_BUILD_DIR)/$@ -r console -a -s diff --git a/Searching/binary search/c/README.md b/Searching/binary search/c/README.md new file mode 100644 index 000000000..880e391dd --- /dev/null +++ b/Searching/binary search/c/README.md @@ -0,0 +1,3 @@ +#### You can run tests with `make unit_test` + +** Enjoy hacktoberfest! ** diff --git a/Searching/binary search/c/binary_search.c b/Searching/binary search/c/binary_search.c new file mode 100644 index 000000000..4dd755e0e --- /dev/null +++ b/Searching/binary search/c/binary_search.c @@ -0,0 +1,20 @@ +int binary_search(int *arr, int size, int item) { + int first = 0; + int last = size - 1; + int middle; + + while (first <= last) { + middle = (last + first) / 2; + if (arr[middle] == item) { + return middle; + } + + if (item < arr[middle]) { + last = middle - 1; + } else if (item > arr[middle]) { + first = middle + 1; + } + }; + + return -1; +} diff --git a/Searching/binary search/c/binary_search.h b/Searching/binary search/c/binary_search.h new file mode 100644 index 000000000..fc20deebd --- /dev/null +++ b/Searching/binary search/c/binary_search.h @@ -0,0 +1,6 @@ +#ifndef BINARY_SEARCH_H +#define BINARY_SEARCH_H + +int binary_search(int *arr, int size, int item); + +#endif diff --git a/Searching/binary search/c/test/binary_search_test.cc b/Searching/binary search/c/test/binary_search_test.cc new file mode 100644 index 000000000..b13971392 --- /dev/null +++ b/Searching/binary search/c/test/binary_search_test.cc @@ -0,0 +1,80 @@ +#include "binary_search.h" +#include "catch.hpp" + +SCENARIO("Testing binary_search", "[binary_search][unit]") { + GIVEN("Sorted integer array with 5 elements") { + int arr[5] = {1, 2, 3, 4, 5}; + + WHEN("binary_search called with given array and elementToFind as 1(first " + "element)") { + int elementToFind = 1; + int actualIndex = binary_search(arr, 5, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = 0; + REQUIRE(actualIndex == expectedIndex); + } + } + + WHEN("binary_search called with given array and elementToFind as 4") { + int elementToFind = 3; + int actualIndex = binary_search(arr, 5, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = 2; + REQUIRE(actualIndex == expectedIndex); + } + } + + WHEN("binary_search called with given array and elementToFind as 12 which " + "is not exists in given array") { + int elementToFind = 12; + int actualIndex = binary_search(arr, 5, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = -1; + REQUIRE(actualIndex == expectedIndex); + } + } + } + GIVEN("Sorted integer array with 15 elements") { + + int arr[15] = {17, 32, 44, 47, 50, 51, 52, 67, 69, 71, 77, 81, 88, 92, 100}; + + WHEN("binary_search called with given array and elementToFind as 44") { + int elementToFind = 44; + int actualIndex = binary_search(arr, 15, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = 2; + REQUIRE(actualIndex == expectedIndex); + } + } + + WHEN("binary_search called with given array and elementToFind as 67(middle " + "element)") { + int elementToFind = 67; + int actualIndex = binary_search(arr, 15, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = 7; + REQUIRE(actualIndex == expectedIndex); + } + } + + WHEN("binary_search called with given array and elementToFind as 17(first " + "element)") { + int elementToFind = 17; + int actualIndex = binary_search(arr, 15, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = 0; + REQUIRE(actualIndex == expectedIndex); + } + } + + WHEN("binary_search called with given array and elementToFind as 100(last " + "element)") { + int elementToFind = 100; + int actualIndex = binary_search(arr, 15, elementToFind); + THEN("actualIndex should equal to expectedIndex") { + int expectedIndex = 14; + REQUIRE(actualIndex == expectedIndex); + } + } + } +} diff --git a/Searching/binary search/c/test/catch.hpp b/Searching/binary search/c/test/catch.hpp new file mode 100644 index 000000000..fdb046fe4 --- /dev/null +++ b/Searching/binary search/c/test/catch.hpp @@ -0,0 +1,11689 @@ +/* + * Catch v1.12.2 + * Generated: 2018-05-14 15:10:01.112442 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + +#define TWOBLUECUBES_CATCH_HPP_INCLUDED + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// #included from: internal/catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic ignored "-Wglobal-constructors" +# pragma clang diagnostic ignored "-Wvariadic-macros" +# pragma clang diagnostic ignored "-Wc99-extensions" +# pragma clang diagnostic ignored "-Wunused-variable" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wc++98-compat" +# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic ignored "-Wvariadic-macros" +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wparentheses" + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wpadded" +#endif +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +#endif + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// #included from: internal/catch_notimplemented_exception.h +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED + +// #included from: catch_common.h +#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED + +// #included from: catch_compiler_capabilities.h +#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? +// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported +// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? +// CATCH_CONFIG_CPP11_OVERRIDE : is override supported? +// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) +// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? +// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? + +// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 + +#ifdef __cplusplus + +# if __cplusplus >= 201103L +# define CATCH_CPP11_OR_GREATER +# endif + +# if __cplusplus >= 201402L +# define CATCH_CPP14_OR_GREATER +# endif + +#endif + +#ifdef __clang__ + +# if __has_feature(cxx_nullptr) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# if __has_feature(cxx_noexcept) +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# if defined(CATCH_CPP11_OR_GREATER) +# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ + _Pragma( "clang diagnostic pop" ) + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic pop" ) +# endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) + +# if !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# endif + +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE + +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Borland +#ifdef __BORLANDC__ + +#endif // __BORLANDC__ + +//////////////////////////////////////////////////////////////////////////////// +// EDG +#ifdef __EDG_VERSION__ + +#endif // __EDG_VERSION__ + +//////////////////////////////////////////////////////////////////////////////// +// Digital Mars +#ifdef __DMC__ + +#endif // __DMC__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH + +#if (_MSC_VER >= 1600) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE +#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// Use variadic macros if the compiler supports them +#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ + ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ + ( defined __GNUC__ && __GNUC__ >= 3 ) || \ + ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) + +#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS + +#endif + +// Use __COUNTER__ if the compiler supports it +#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ + ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ + ( defined __clang__ && __clang_major__ >= 3 ) + +// Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former, +// because __COUNTER__ is not properly handled by it. +// This does not affect compilation +#if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +#endif + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(CATCH_CPP11_OR_GREATER) + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# endif + +# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# endif + +# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) +# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG +# endif + +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) +# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) +# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE +# endif +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) +# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS +# endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NULLPTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_IS_ENUM +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TUPLE +#endif +#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) +# define CATCH_CONFIG_VARIADIC_MACROS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_LONG_LONG +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_UNIQUE_PTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_SHUFFLE +#endif +# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TYPE_TRAITS +# endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS +#endif + +// noexcept support: +#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) +# define CATCH_NOEXCEPT noexcept +# define CATCH_NOEXCEPT_IS(x) noexcept(x) +#else +# define CATCH_NOEXCEPT throw() +# define CATCH_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_NULL nullptr +#else +# define CATCH_NULL NULL +#endif + +// override support +#ifdef CATCH_CONFIG_CPP11_OVERRIDE +# define CATCH_OVERRIDE override +#else +# define CATCH_OVERRIDE +#endif + +// unique_ptr support +#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR +# define CATCH_AUTO_PTR( T ) std::unique_ptr +#else +# define CATCH_AUTO_PTR( T ) std::auto_ptr +#endif + +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr +#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) + +#include +#include + +namespace Catch { + + struct IConfig; + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { +#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; +#else + NonCopyable( NonCopyable const& info ); + NonCopyable& operator = ( NonCopyable const& ); +#endif + + protected: + NonCopyable() {} + virtual ~NonCopyable(); + }; + + class SafeBool { + public: + typedef void (SafeBool::*type)() const; + + static type makeSafe( bool value ) { + return value ? &SafeBool::trueValue : 0; + } + private: + void trueValue() const {} + }; + + template + void deleteAll( ContainerT& container ) { + typename ContainerT::const_iterator it = container.begin(); + typename ContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete *it; + } + template + void deleteAllValues( AssociativeContainerT& container ) { + typename AssociativeContainerT::const_iterator it = container.begin(); + typename AssociativeContainerT::const_iterator itEnd = container.end(); + for(; it != itEnd; ++it ) + delete it->second; + } + + bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + std::string trim( std::string const& str ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; + + struct SourceLineInfo { + + SourceLineInfo(); + SourceLineInfo( char const* _file, std::size_t _line ); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SourceLineInfo(SourceLineInfo const& other) = default; + SourceLineInfo( SourceLineInfo && ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo& operator = ( SourceLineInfo && ) = default; +# endif + bool empty() const; + bool operator == ( SourceLineInfo const& other ) const; + bool operator < ( SourceLineInfo const& other ) const; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // This is just here to avoid compiler warnings with macro constants and boolean literals + inline bool isTrue( bool value ){ return value; } + inline bool alwaysTrue() { return true; } + inline bool alwaysFalse() { return false; } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); + + void seedRng( IConfig const& config ); + unsigned int rngSeed(); + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() { + return std::string(); + } + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); + +namespace Catch { + + class NotImplementedException : public std::exception + { + public: + NotImplementedException( SourceLineInfo const& lineInfo ); + + virtual ~NotImplementedException() CATCH_NOEXCEPT {} + + virtual const char* what() const CATCH_NOEXCEPT; + + private: + std::string m_what; + SourceLineInfo m_lineInfo; + }; + +} // end namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) + +// #included from: internal/catch_context.h +#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED + +// #included from: catch_interfaces_generators.h +#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED + +#include + +namespace Catch { + + struct IGeneratorInfo { + virtual ~IGeneratorInfo(); + virtual bool moveNext() = 0; + virtual std::size_t getCurrentIndex() const = 0; + }; + + struct IGeneratorsForTest { + virtual ~IGeneratorsForTest(); + + virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; + virtual bool moveNext() = 0; + }; + + IGeneratorsForTest* createGeneratorsForTest(); + +} // end namespace Catch + +// #included from: catch_ptr.hpp +#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + // An intrusive reference counting smart pointer. + // T must implement addRef() and release() methods + // typically implementing the IShared interface + template + class Ptr { + public: + Ptr() : m_p( CATCH_NULL ){} + Ptr( T* p ) : m_p( p ){ + if( m_p ) + m_p->addRef(); + } + Ptr( Ptr const& other ) : m_p( other.m_p ){ + if( m_p ) + m_p->addRef(); + } + ~Ptr(){ + if( m_p ) + m_p->release(); + } + void reset() { + if( m_p ) + m_p->release(); + m_p = CATCH_NULL; + } + Ptr& operator = ( T* p ){ + Ptr temp( p ); + swap( temp ); + return *this; + } + Ptr& operator = ( Ptr const& other ){ + Ptr temp( other ); + swap( temp ); + return *this; + } + void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } + T* get() const{ return m_p; } + T& operator*() const { return *m_p; } + T* operator->() const { return m_p; } + bool operator !() const { return m_p == CATCH_NULL; } + operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } + + private: + T* m_p; + }; + + struct IShared : NonCopyable { + virtual ~IShared(); + virtual void addRef() const = 0; + virtual void release() const = 0; + }; + + template + struct SharedImpl : T { + + SharedImpl() : m_rc( 0 ){} + + virtual void addRef() const { + ++m_rc; + } + virtual void release() const { + if( --m_rc == 0 ) + delete this; + } + + mutable unsigned int m_rc; + }; + +} // end namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +namespace Catch { + + class TestCase; + class Stream; + struct IResultCapture; + struct IRunner; + struct IGeneratorsForTest; + struct IConfig; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; + virtual bool advanceGeneratorsForCurrentTest() = 0; + virtual Ptr getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( Ptr const& config ) = 0; + }; + + IContext& getCurrentContext(); + IMutableContext& getCurrentMutableContext(); + void cleanUpContext(); + Stream createStream( std::string const& streamName ); + +} + +// #included from: internal/catch_test_registry.hpp +#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED + +// #included from: catch_interfaces_testcase.h +#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED + +#include + +namespace Catch { + + class TestSpec; + + struct ITestCase : IShared { + virtual void invoke () const = 0; + protected: + virtual ~ITestCase(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +namespace Catch { + +template +class MethodTestCase : public SharedImpl { + +public: + MethodTestCase( void (C::*method)() ) : m_method( method ) {} + + virtual void invoke() const { + C obj; + (obj.*m_method)(); + } + +private: + virtual ~MethodTestCase() {} + + void (C::*m_method)(); +}; + +typedef void(*TestFunction)(); + +struct NameAndDesc { + NameAndDesc( const char* _name = "", const char* _description= "" ) + : name( _name ), description( _description ) + {} + + const char* name; + const char* description; +}; + +void registerTestCase + ( ITestCase* testCase, + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ); + +struct AutoReg { + + AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + + template + AutoReg + ( void (C::*method)(), + char const* className, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + registerTestCase + ( new MethodTestCase( method ), + className, + nameAndDesc, + lineInfo ); + } + + ~AutoReg(); + +private: + AutoReg( AutoReg const& ); + void operator= ( AutoReg const& ); +}; + +void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ); + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + namespace{ \ + struct TestName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ + } \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS + +#else + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ + static void TestName(); \ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + namespace{ \ + struct TestCaseName : ClassName{ \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); /* NOLINT */ \ + } \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ + void TestCaseName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ + CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ + Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS + +#endif + +// #included from: internal/catch_capture.hpp +#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED + +// #included from: catch_result_builder.h +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED + +// #included from: catch_result_type.h +#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + inline bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + inline bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast( static_cast( lhs ) | static_cast( rhs ) ); + } + + inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch + +// #included from: catch_assertionresult.h +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED + +#include + +namespace Catch { + + struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; + + struct DecomposedExpression + { + virtual ~DecomposedExpression() {} + virtual bool isBinaryExpression() const { + return false; + } + virtual void reconstructExpression( std::string& dest ) const = 0; + + // Only simple binary comparisons can be decomposed. + // If more complex check is required then wrap sub-expressions in parentheses. + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator % ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( T const& ); + template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( T const& ); + + private: + DecomposedExpression& operator = (DecomposedExpression const&); + }; + + struct AssertionInfo + { + AssertionInfo(); + AssertionInfo( char const * _macroName, + SourceLineInfo const& _lineInfo, + char const * _capturedExpression, + ResultDisposition::Flags _resultDisposition, + char const * _secondArg = ""); + + char const * macroName; + SourceLineInfo lineInfo; + char const * capturedExpression; + ResultDisposition::Flags resultDisposition; + char const * secondArg; + }; + + struct AssertionResultData + { + AssertionResultData() : decomposedExpression( CATCH_NULL ) + , resultType( ResultWas::Unknown ) + , negated( false ) + , parenthesized( false ) {} + + void negate( bool parenthesize ) { + negated = !negated; + parenthesized = parenthesize; + if( resultType == ResultWas::Ok ) + resultType = ResultWas::ExpressionFailed; + else if( resultType == ResultWas::ExpressionFailed ) + resultType = ResultWas::Ok; + } + + std::string const& reconstructExpression() const { + if( decomposedExpression != CATCH_NULL ) { + decomposedExpression->reconstructExpression( reconstructedExpression ); + if( parenthesized ) { + reconstructedExpression.insert( 0, 1, '(' ); + reconstructedExpression.append( 1, ')' ); + } + if( negated ) { + reconstructedExpression.insert( 0, 1, '!' ); + } + decomposedExpression = CATCH_NULL; + } + return reconstructedExpression; + } + + mutable DecomposedExpression const* decomposedExpression; + mutable std::string reconstructedExpression; + std::string message; + ResultWas::OfType resultType; + bool negated; + bool parenthesized; + }; + + class AssertionResult { + public: + AssertionResult(); + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + ~AssertionResult(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionResult( AssertionResult const& ) = default; + AssertionResult( AssertionResult && ) = default; + AssertionResult& operator = ( AssertionResult const& ) = default; + AssertionResult& operator = ( AssertionResult && ) = default; +# endif + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + std::string getTestMacroName() const; + void discardDecomposedExpression() const; + void expandDecomposedExpression() const; + + protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +// #included from: catch_matchers.hpp +#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED + +namespace Catch { +namespace Matchers { + namespace Impl { + + template struct MatchAllOf; + template struct MatchAnyOf; + template struct MatchNotOf; + + class MatcherUntypedBase { + public: + std::string toString() const { + if( m_cachedToString.empty() ) + m_cachedToString = describe(); + return m_cachedToString; + } + + protected: + virtual ~MatcherUntypedBase(); + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; + private: + MatcherUntypedBase& operator = ( MatcherUntypedBase const& ); + }; + + template + struct MatcherMethod { + virtual bool match( ObjectT const& arg ) const = 0; + }; + template + struct MatcherMethod { + virtual bool match( PtrT* arg ) const = 0; + }; + + template + struct MatcherBase : MatcherUntypedBase, MatcherMethod { + + MatchAllOf operator && ( MatcherBase const& other ) const; + MatchAnyOf operator || ( MatcherBase const& other ) const; + MatchNotOf operator ! () const; + }; + + template + struct MatchAllOf : MatcherBase { + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if (!m_matchers[i]->match(arg)) + return false; + } + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + description += " and "; + description += m_matchers[i]->toString(); + } + description += " )"; + return description; + } + + MatchAllOf& operator && ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + template + struct MatchAnyOf : MatcherBase { + + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if (m_matchers[i]->match(arg)) + return true; + } + return false; + } + virtual std::string describe() const CATCH_OVERRIDE { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + for( std::size_t i = 0; i < m_matchers.size(); ++i ) { + if( i != 0 ) + description += " or "; + description += m_matchers[i]->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf& operator || ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + + template + struct MatchNotOf : MatcherBase { + + MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} + + virtual bool match( ArgT const& arg ) const CATCH_OVERRIDE { + return !m_underlyingMatcher.match( arg ); + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase const& m_underlyingMatcher; + }; + + template + MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { + return MatchAllOf() && *this && other; + } + template + MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { + return MatchAnyOf() || *this || other; + } + template + MatchNotOf MatcherBase::operator ! () const { + return MatchNotOf( *this ); + } + + } // namespace Impl + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + // - deprecated: prefer ||, && and ! + template + Impl::MatchNotOf Not( Impl::MatcherBase const& underlyingMatcher ) { + return Impl::MatchNotOf( underlyingMatcher ); + } + template + Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { + return Impl::MatchAllOf() && m1 && m2; + } + template + Impl::MatchAllOf AllOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { + return Impl::MatchAllOf() && m1 && m2 && m3; + } + template + Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2 ) { + return Impl::MatchAnyOf() || m1 || m2; + } + template + Impl::MatchAnyOf AnyOf( Impl::MatcherBase const& m1, Impl::MatcherBase const& m2, Impl::MatcherBase const& m3 ) { + return Impl::MatchAnyOf() || m1 || m2 || m3; + } + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +namespace Catch { + + struct TestFailureException{}; + + template class ExpressionLhs; + + struct CopyableStream { + CopyableStream() {} + CopyableStream( CopyableStream const& other ) { + oss << other.oss.str(); + } + CopyableStream& operator=( CopyableStream const& other ) { + oss.str(std::string()); + oss << other.oss.str(); + return *this; + } + std::ostringstream oss; + }; + + class ResultBuilder : public DecomposedExpression { + public: + ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg = "" ); + ~ResultBuilder(); + + template + ExpressionLhs operator <= ( T const& operand ); + ExpressionLhs operator <= ( bool value ); + + template + ResultBuilder& operator << ( T const& value ) { + stream().oss << value; + return *this; + } + + ResultBuilder& setResultType( ResultWas::OfType result ); + ResultBuilder& setResultType( bool result ); + + void endExpression( DecomposedExpression const& expr ); + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE; + + AssertionResult build() const; + AssertionResult build( DecomposedExpression const& expr ) const; + + void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); + void captureResult( ResultWas::OfType resultType ); + void captureExpression(); + void captureExpectedException( std::string const& expectedMessage ); + void captureExpectedException( Matchers::Impl::MatcherBase const& matcher ); + void handleResult( AssertionResult const& result ); + void react(); + bool shouldDebugBreak() const; + bool allowThrows() const; + + template + void captureMatch( ArgT const& arg, MatcherT const& matcher, char const* matcherString ); + + void setExceptionGuard(); + void unsetExceptionGuard(); + + private: + AssertionInfo m_assertionInfo; + AssertionResultData m_data; + + CopyableStream &stream() + { + if(!m_usedStream) + { + m_usedStream = true; + m_stream().oss.str(""); + } + return m_stream(); + } + + static CopyableStream &m_stream() + { + static CopyableStream s; + return s; + } + + bool m_shouldDebugBreak; + bool m_shouldThrow; + bool m_guardException; + bool m_usedStream; + }; + +} // namespace Catch + +// Include after due to circular dependency: +// #included from: catch_expression_lhs.hpp +#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED + +// #included from: catch_evaluate.hpp +#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#pragma warning(disable:4018) // more "signed/unsigned mismatch" +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#endif + +#include + +namespace Catch { +namespace Internal { + + enum Operator { + IsEqualTo, + IsNotEqualTo, + IsLessThan, + IsGreaterThan, + IsLessThanOrEqualTo, + IsGreaterThanOrEqualTo + }; + + template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; + template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; + template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; + template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; + + template + T& opCast(T const& t) { return const_cast(t); } + +// nullptr_t support based on pull request #154 from Konstantin Baumann +#ifdef CATCH_CONFIG_CPP11_NULLPTR + inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } +#endif // CATCH_CONFIG_CPP11_NULLPTR + + // So the compare overloads can be operator agnostic we convey the operator as a template + // enum, which is used to specialise an Evaluator for doing the comparison. + template + struct Evaluator{}; + + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs) { + return bool( opCast( lhs ) == opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) != opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) < opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) > opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) >= opCast( rhs ) ); + } + }; + template + struct Evaluator { + static bool evaluate( T1 const& lhs, T2 const& rhs ) { + return bool( opCast( lhs ) <= opCast( rhs ) ); + } + }; + + template + bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // This level of indirection allows us to specialise for integer types + // to avoid signed/ unsigned warnings + + // "base" overload + template + bool compare( T1 const& lhs, T2 const& rhs ) { + return Evaluator::evaluate( lhs, rhs ); + } + + // unsigned X to int + template bool compare( unsigned int lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, int rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // unsigned X to long + template bool compare( unsigned int lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned long lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + template bool compare( unsigned char lhs, long rhs ) { + return applyEvaluator( lhs, static_cast( rhs ) ); + } + + // int to unsigned X + template bool compare( int lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( int lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // long to unsigned X + template bool compare( long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long (when comparing against NULL) + template bool compare( long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + + // pointer to int (when comparing against NULL) + template bool compare( int lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, int rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG + // long long to unsigned X + template bool compare( long long lhs, unsigned int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( long long lhs, unsigned char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // unsigned long long to X + template bool compare( unsigned long long lhs, int rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, long long rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + template bool compare( unsigned long long lhs, char rhs ) { + return applyEvaluator( static_cast( lhs ), rhs ); + } + + // pointer to long long (when comparing against NULL) + template bool compare( long long lhs, T* rhs ) { + return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); + } + template bool compare( T* lhs, long long rhs ) { + return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); + } +#endif // CATCH_CONFIG_CPP11_LONG_LONG + +#ifdef CATCH_CONFIG_CPP11_NULLPTR + // pointer to nullptr_t (when comparing against nullptr) + template bool compare( std::nullptr_t, T* rhs ) { + return Evaluator::evaluate( nullptr, rhs ); + } + template bool compare( T* lhs, std::nullptr_t ) { + return Evaluator::evaluate( lhs, nullptr ); + } +#endif // CATCH_CONFIG_CPP11_NULLPTR + +} // end of namespace Internal +} // end of namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// #included from: catch_tostring.h +#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED + +#include +#include +#include +#include +#include + +#ifdef __OBJC__ +// #included from: catch_objc_arc.hpp +#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED + +#import + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +#endif + +#ifdef CATCH_CONFIG_CPP11_TUPLE +#include +#endif + +#ifdef CATCH_CONFIG_CPP11_IS_ENUM +#include +#endif + +namespace Catch { + +// Why we're here. +template +std::string toString( T const& value ); + +// Built in overloads + +std::string toString( std::string const& value ); +std::string toString( std::wstring const& value ); +std::string toString( const char* const value ); +std::string toString( char* const value ); +std::string toString( const wchar_t* const value ); +std::string toString( wchar_t* const value ); +std::string toString( int value ); +std::string toString( unsigned long value ); +std::string toString( unsigned int value ); +std::string toString( const double value ); +std::string toString( const float value ); +std::string toString( bool value ); +std::string toString( char value ); +std::string toString( signed char value ); +std::string toString( unsigned char value ); + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ); +std::string toString( unsigned long long value ); +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ); +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ); + std::string toString( NSString * CATCH_ARC_STRONG & nsstring ); + std::string toString( NSObject* const& nsObject ); +#endif + +namespace Detail { + + extern const std::string unprintableString; + + #if !defined(CATCH_CONFIG_CPP11_STREAM_INSERTABLE_CHECK) + struct BorgType { + template BorgType( T const& ); + }; + + struct TrueType { char sizer[1]; }; + struct FalseType { char sizer[2]; }; + + TrueType& testStreamable( std::ostream& ); + FalseType testStreamable( FalseType ); + + FalseType operator<<( std::ostream const&, BorgType const& ); + + template + struct IsStreamInsertable { + static std::ostream &s; + static T const&t; + enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; + }; +#else + template + class IsStreamInsertable { + template + static auto test(int) + -> decltype( std::declval() << std::declval(), std::true_type() ); + + template + static auto test(...) -> std::false_type; + + public: + static const bool value = decltype(test(0))::value; + }; +#endif + +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template::value + > + struct EnumStringMaker + { + static std::string convert( T const& ) { return unprintableString; } + }; + + template + struct EnumStringMaker + { + static std::string convert( T const& v ) + { + return ::Catch::toString( + static_cast::type>(v) + ); + } + }; +#endif + template + struct StringMakerBase { +#if defined(CATCH_CONFIG_CPP11_IS_ENUM) + template + static std::string convert( T const& v ) + { + return EnumStringMaker::convert( v ); + } +#else + template + static std::string convert( T const& ) { return unprintableString; } +#endif + }; + + template<> + struct StringMakerBase { + template + static std::string convert( T const& _value ) { + std::ostringstream oss; + oss << _value; + return oss.str(); + } + }; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template + std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + +} // end namespace Detail + +template +struct StringMaker : + Detail::StringMakerBase::value> {}; + +template +struct StringMaker { + template + static std::string convert( U* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +template +struct StringMaker { + static std::string convert( R C::* p ) { + if( !p ) + return "NULL"; + else + return Detail::rawMemoryToString( p ); + } +}; + +namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ); +} + +//template +//struct StringMaker > { +// static std::string convert( std::vector const& v ) { +// return Detail::rangeToString( v.begin(), v.end() ); +// } +//}; + +template +std::string toString( std::vector const& v ) { + return Detail::rangeToString( v.begin(), v.end() ); +} + +#ifdef CATCH_CONFIG_CPP11_TUPLE + +// toString for tuples +namespace TupleDetail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size::value) + > + struct ElementPrinter { + static void print( const Tuple& tuple, std::ostream& os ) + { + os << ( N ? ", " : " " ) + << Catch::toString(std::get(tuple)); + ElementPrinter::print(tuple,os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct ElementPrinter { + static void print( const Tuple&, std::ostream& ) {} + }; + +} + +template +struct StringMaker> { + + static std::string convert( const std::tuple& tuple ) + { + std::ostringstream os; + os << '{'; + TupleDetail::ElementPrinter>::print( tuple, os ); + os << " }"; + return os.str(); + } +}; +#endif // CATCH_CONFIG_CPP11_TUPLE + +namespace Detail { + template + std::string makeString( T const& value ) { + return StringMaker::convert( value ); + } +} // end namespace Detail + +/// \brief converts any type to a string +/// +/// The default template forwards on to ostringstream - except when an +/// ostringstream overload does not exist - in which case it attempts to detect +/// that and writes {?}. +/// Overload (not specialise) this template for custom typs that you don't want +/// to provide an ostream overload for. +template +std::string toString( T const& value ) { + return StringMaker::convert( value ); +} + + namespace Detail { + template + std::string rangeToString( InputIterator first, InputIterator last ) { + std::ostringstream oss; + oss << "{ "; + if( first != last ) { + oss << Catch::toString( *first ); + for( ++first ; first != last ; ++first ) + oss << ", " << Catch::toString( *first ); + } + oss << " }"; + return oss.str(); + } +} + +} // end namespace Catch + +namespace Catch { + +template +class BinaryExpression; + +template +class MatchExpression; + +// Wraps the LHS of an expression and overloads comparison operators +// for also capturing those and RHS (if any) +template +class ExpressionLhs : public DecomposedExpression { +public: + ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ), m_truthy(false) {} + + ExpressionLhs& operator = ( const ExpressionLhs& ); + + template + BinaryExpression + operator == ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator != ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator < ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator > ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator <= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + template + BinaryExpression + operator >= ( RhsT const& rhs ) { + return captureExpression( rhs ); + } + + BinaryExpression operator == ( bool rhs ) { + return captureExpression( rhs ); + } + + BinaryExpression operator != ( bool rhs ) { + return captureExpression( rhs ); + } + + void endExpression() { + m_truthy = m_lhs ? true : false; + m_rb + .setResultType( m_truthy ) + .endExpression( *this ); + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + dest = Catch::toString( m_lhs ); + } + +private: + template + BinaryExpression captureExpression( RhsT& rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + + template + BinaryExpression captureExpression( bool rhs ) const { + return BinaryExpression( m_rb, m_lhs, rhs ); + } + +private: + ResultBuilder& m_rb; + T m_lhs; + bool m_truthy; +}; + +template +class BinaryExpression : public DecomposedExpression { +public: + BinaryExpression( ResultBuilder& rb, LhsT lhs, RhsT rhs ) + : m_rb( rb ), m_lhs( lhs ), m_rhs( rhs ) {} + + BinaryExpression& operator = ( BinaryExpression& ); + + void endExpression() const { + m_rb + .setResultType( Internal::compare( m_lhs, m_rhs ) ) + .endExpression( *this ); + } + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string lhs = Catch::toString( m_lhs ); + std::string rhs = Catch::toString( m_rhs ); + char delim = lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ? ' ' : '\n'; + dest.reserve( 7 + lhs.size() + rhs.size() ); + // 2 for spaces around operator + // 2 for operator + // 2 for parentheses (conditionally added later) + // 1 for negation (conditionally added later) + dest = lhs; + dest += delim; + dest += Internal::OperatorTraits::getName(); + dest += delim; + dest += rhs; + } + +private: + ResultBuilder& m_rb; + LhsT m_lhs; + RhsT m_rhs; +}; + +template +class MatchExpression : public DecomposedExpression { +public: + MatchExpression( ArgT arg, MatcherT matcher, char const* matcherString ) + : m_arg( arg ), m_matcher( matcher ), m_matcherString( matcherString ) {} + + virtual bool isBinaryExpression() const CATCH_OVERRIDE { + return true; + } + + virtual void reconstructExpression( std::string& dest ) const CATCH_OVERRIDE { + std::string matcherAsString = m_matcher.toString(); + dest = Catch::toString( m_arg ); + dest += ' '; + if( matcherAsString == Detail::unprintableString ) + dest += m_matcherString; + else + dest += matcherAsString; + } + +private: + ArgT m_arg; + MatcherT m_matcher; + char const* m_matcherString; +}; + +} // end namespace Catch + + +namespace Catch { + + template + ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { + return ExpressionLhs( *this, operand ); + } + + inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { + return ExpressionLhs( *this, value ); + } + + template + void ResultBuilder::captureMatch( ArgT const& arg, MatcherT const& matcher, + char const* matcherString ) { + MatchExpression expr( arg, matcher, matcherString ); + setResultType( matcher.match( arg ) ); + endExpression( expr ); + } + +} // namespace Catch + +// #included from: catch_message.h +#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED + +#include + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + SourceLineInfo lineInfo; + ResultWas::OfType type; + std::string message; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const { + return sequence == other.sequence; + } + bool operator < ( MessageInfo const& other ) const { + return sequence < other.sequence; + } + private: + static unsigned int globalCount; + }; + + struct MessageBuilder { + MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + : m_info( macroName, lineInfo, type ) + {} + + template + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + std::ostringstream m_stream; + }; + + class ScopedMessage { + public: + ScopedMessage( MessageBuilder const& builder ); + ScopedMessage( ScopedMessage const& other ); + ~ScopedMessage(); + + MessageInfo m_info; + }; + +} // end namespace Catch + +// #included from: catch_interfaces_capture.h +#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED + +#include + +namespace Catch { + + class TestCase; + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + class ScopedMessageBuilder; + struct Counts; + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual void assertionEnded( AssertionResult const& result ) = 0; + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + + virtual void exceptionEarlyReported() = 0; + + virtual void handleFatalErrorCondition( std::string const& message ) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + virtual void assertionRun() = 0; + }; + + IResultCapture& getResultCapture(); +} + +// #included from: catch_debugger.h +#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED + +// #included from: catch_platform.h +#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED + +#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# define CATCH_PLATFORM_MAC +#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +# define CATCH_PLATFORM_IPHONE +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +# define CATCH_PLATFORM_WINDOWS +# if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINES_NOMINMAX +# endif +# if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# endif +#endif + +#include + +namespace Catch{ + + bool isDebuggerActive(); + void writeToDebugConsole( std::string const& text ); +} + +#ifdef CATCH_PLATFORM_MAC + + // The following code snippet based on: + // http://cocoawithlove.com/2008/03/break-into-debugger.html + #if defined(__ppc64__) || defined(__ppc__) + #define CATCH_TRAP() \ + __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ + : : : "memory","r0","r3","r4" ) /* NOLINT */ + #else + #define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ ) + #endif + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ + #else // Fall back to the generic way. + #include + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } +#else + #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); +#endif + +// #included from: catch_interfaces_runner.h +#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED + +namespace Catch { + class TestCase; + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) +# define CATCH_INTERNAL_STRINGIFY(expr) #expr +#else +# define CATCH_INTERNAL_STRINGIFY(expr) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" +#endif + +#if defined(CATCH_CONFIG_FAST_COMPILE) +/////////////////////////////////////////////////////////////////////////////// +// We can speedup compilation significantly by breaking into debugger lower in +// the callstack, because then we don't have to expand CATCH_BREAK_INTO_DEBUGGER +// macro in each assertion +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + resultBuilder.react(); + +/////////////////////////////////////////////////////////////////////////////// +// Another way to speed-up compilation is to omit local try-catch for REQUIRE* +// macros. +// This can potentially cause false negative, if the test code catches +// the exception before it propagates back up to the runner. +#define INTERNAL_CATCH_TEST_NO_TRY( macroName, resultDisposition, expr ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ + __catchResult.setExceptionGuard(); \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + ( __catchResult <= expr ).endExpression(); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + __catchResult.unsetExceptionGuard(); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look +// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +#define INTERNAL_CHECK_THAT_NO_TRY( macroName, matcher, resultDisposition, arg ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + __catchResult.setExceptionGuard(); \ + __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ + __catchResult.unsetExceptionGuard(); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +#else +/////////////////////////////////////////////////////////////////////////////// +// In the event of a failure works out if the debugger needs to be invoked +// and/or an exception thrown and takes appropriate action. +// This needs to be done as a macro so the debugger will stop in the user +// source code rather than in Catch library code +#define INTERNAL_CATCH_REACT( resultBuilder ) \ + if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ + resultBuilder.react(); +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ + try { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + ( __catchResult <= expr ).endExpression(); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::isTrue( false && static_cast( !!(expr) ) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look + // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( macroName, resultDisposition, expr ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ + if( Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, expr ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, expr ); \ + if( !Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, expr ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition ); \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, matcher, expr ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr), resultDisposition, CATCH_INTERNAL_STRINGIFY(matcher) ); \ + if( __catchResult.allowThrows() ) \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( ... ) { \ + __catchResult.captureExpectedException( matcher ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ + if( __catchResult.allowThrows() ) \ + try { \ + static_cast(expr); \ + __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ + } \ + catch( exceptionType ) { \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + } \ + catch( ... ) { \ + __catchResult.useActiveException( resultDisposition ); \ + } \ + else \ + __catchResult.captureResult( Catch::ResultWas::Ok ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +/////////////////////////////////////////////////////////////////////////////// +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#else + #define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, log ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + __catchResult << log + ::Catch::StreamEndStop(); \ + __catchResult.captureResult( messageType ); \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( macroName, log ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ + do { \ + Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + try { \ + __catchResult.captureMatch( arg, matcher, CATCH_INTERNAL_STRINGIFY(matcher) ); \ + } catch( ... ) { \ + __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ + } \ + INTERNAL_CATCH_REACT( __catchResult ) \ + } while( Catch::alwaysFalse() ) + +// #included from: internal/catch_section.h +#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED + +// #included from: catch_section_info.h +#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED + +// #included from: catch_totals.hpp +#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED + +#include + +namespace Catch { + + struct Counts { + Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} + + Counts operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + Counts& operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t total() const { + return passed + failed + failedButOk; + } + bool allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool allOk() const { + return failed == 0; + } + + std::size_t passed; + std::size_t failed; + std::size_t failedButOk; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + + Totals& operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Counts assertions; + Counts testCases; + }; +} + +#include + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description = std::string() ); + + std::string name; + std::string description; + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) + : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) + {} + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +// #included from: catch_timer.h +#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED + +#ifdef _MSC_VER + +namespace Catch { + typedef unsigned long long UInt64; +} +#else +#include +namespace Catch { + typedef uint64_t UInt64; +} +#endif + +namespace Catch { + class Timer { + public: + Timer() : m_ticks( 0 ) {} + void start(); + unsigned int getElapsedMicroseconds() const; + unsigned int getElapsedMilliseconds() const; + double getElapsedSeconds() const; + + private: + UInt64 m_ticks; + }; + +} // namespace Catch + +#include + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define INTERNAL_CATCH_SECTION( ... ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) +#else + #define INTERNAL_CATCH_SECTION( name, desc ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) +#endif + +// #included from: internal/catch_generators.hpp +#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + +template +struct IGenerator { + virtual ~IGenerator() {} + virtual T getValue( std::size_t index ) const = 0; + virtual std::size_t size () const = 0; +}; + +template +class BetweenGenerator : public IGenerator { +public: + BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} + + virtual T getValue( std::size_t index ) const { + return m_from+static_cast( index ); + } + + virtual std::size_t size() const { + return static_cast( 1+m_to-m_from ); + } + +private: + + T m_from; + T m_to; +}; + +template +class ValuesGenerator : public IGenerator { +public: + ValuesGenerator(){} + + void add( T value ) { + m_values.push_back( value ); + } + + virtual T getValue( std::size_t index ) const { + return m_values[index]; + } + + virtual std::size_t size() const { + return m_values.size(); + } + +private: + std::vector m_values; +}; + +template +class CompositeGenerator { +public: + CompositeGenerator() : m_totalSize( 0 ) {} + + // *** Move semantics, similar to auto_ptr *** + CompositeGenerator( CompositeGenerator& other ) + : m_fileInfo( other.m_fileInfo ), + m_totalSize( 0 ) + { + move( other ); + } + + CompositeGenerator& setFileInfo( const char* fileInfo ) { + m_fileInfo = fileInfo; + return *this; + } + + ~CompositeGenerator() { + deleteAll( m_composed ); + } + + operator T () const { + size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); + + typename std::vector*>::const_iterator it = m_composed.begin(); + typename std::vector*>::const_iterator itEnd = m_composed.end(); + for( size_t index = 0; it != itEnd; ++it ) + { + const IGenerator* generator = *it; + if( overallIndex >= index && overallIndex < index + generator->size() ) + { + return generator->getValue( overallIndex-index ); + } + index += generator->size(); + } + CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); + return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so + } + + void add( const IGenerator* generator ) { + m_totalSize += generator->size(); + m_composed.push_back( generator ); + } + + CompositeGenerator& then( CompositeGenerator& other ) { + move( other ); + return *this; + } + + CompositeGenerator& then( T value ) { + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( value ); + add( valuesGen ); + return *this; + } + +private: + + void move( CompositeGenerator& other ) { + m_composed.insert( m_composed.end(), other.m_composed.begin(), other.m_composed.end() ); + m_totalSize += other.m_totalSize; + other.m_composed.clear(); + } + + std::vector*> m_composed; + std::string m_fileInfo; + size_t m_totalSize; +}; + +namespace Generators +{ + template + CompositeGenerator between( T from, T to ) { + CompositeGenerator generators; + generators.add( new BetweenGenerator( from, to ) ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3 ){ + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + generators.add( valuesGen ); + return generators; + } + + template + CompositeGenerator values( T val1, T val2, T val3, T val4 ) { + CompositeGenerator generators; + ValuesGenerator* valuesGen = new ValuesGenerator(); + valuesGen->add( val1 ); + valuesGen->add( val2 ); + valuesGen->add( val3 ); + valuesGen->add( val4 ); + generators.add( valuesGen ); + return generators; + } + +} // end namespace Generators + +using namespace Generators; + +} // end namespace Catch + +#define INTERNAL_CATCH_LINESTR2( line ) #line +#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) + +#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) + +// #included from: internal/catch_interfaces_exception.h +#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED + +#include +#include + +// #included from: catch_interfaces_registry_hub.h +#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED + +#include + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + struct ITagAliasRegistry; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; + + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; + virtual void registerListener( Ptr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; + }; + + IRegistryHub& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +namespace Catch { + + typedef std::string(*exceptionTranslateFunction)(); + + struct IExceptionTranslator; + typedef std::vector ExceptionTranslators; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { + try { + if( it == itEnd ) + throw; + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// #included from: internal/catch_approx.hpp +#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED + +#include +#include + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) +#include +#endif + +namespace Catch { +namespace Detail { + + class Approx { + public: + explicit Approx ( double value ) + : m_epsilon( std::numeric_limits::epsilon()*100 ), + m_margin( 0.0 ), + m_scale( 1.0 ), + m_value( value ) + {} + + static Approx custom() { + return Approx( 0 ); + } + +#if defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) + + template ::value>::type> + Approx operator()( T value ) { + Approx approx( static_cast(value) ); + approx.epsilon( m_epsilon ); + approx.margin( m_margin ); + approx.scale( m_scale ); + return approx; + } + + template ::value>::type> + explicit Approx( T value ): Approx(static_cast(value)) + {} + + template ::value>::type> + friend bool operator == ( const T& lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + auto lhs_v = double(lhs); + bool relativeOK = std::fabs(lhs_v - rhs.m_value) < rhs.m_epsilon * (rhs.m_scale + (std::max)(std::fabs(lhs_v), std::fabs(rhs.m_value))); + if (relativeOK) { + return true; + } + + return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin; + } + + template ::value>::type> + friend bool operator == ( Approx const& lhs, const T& rhs ) { + return operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator != ( T lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + template ::value>::type> + friend bool operator != ( Approx const& lhs, T rhs ) { + return !operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator <= ( T lhs, Approx const& rhs ) { + return double(lhs) < rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator <= ( Approx const& lhs, T rhs ) { + return lhs.m_value < double(rhs) || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( T lhs, Approx const& rhs ) { + return double(lhs) > rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( Approx const& lhs, T rhs ) { + return lhs.m_value > double(rhs) || lhs == rhs; + } + + template ::value>::type> + Approx& epsilon( T newEpsilon ) { + m_epsilon = double(newEpsilon); + return *this; + } + + template ::value>::type> + Approx& margin( T newMargin ) { + m_margin = double(newMargin); + return *this; + } + + template ::value>::type> + Approx& scale( T newScale ) { + m_scale = double(newScale); + return *this; + } + +#else + + Approx operator()( double value ) { + Approx approx( value ); + approx.epsilon( m_epsilon ); + approx.margin( m_margin ); + approx.scale( m_scale ); + return approx; + } + + friend bool operator == ( double lhs, Approx const& rhs ) { + // Thanks to Richard Harris for his help refining this formula + bool relativeOK = std::fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( std::fabs(lhs), std::fabs(rhs.m_value) ) ); + if (relativeOK) { + return true; + } + return std::fabs(lhs - rhs.m_value) <= rhs.m_margin; + } + + friend bool operator == ( Approx const& lhs, double rhs ) { + return operator==( rhs, lhs ); + } + + friend bool operator != ( double lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + friend bool operator != ( Approx const& lhs, double rhs ) { + return !operator==( rhs, lhs ); + } + + friend bool operator <= ( double lhs, Approx const& rhs ) { + return lhs < rhs.m_value || lhs == rhs; + } + + friend bool operator <= ( Approx const& lhs, double rhs ) { + return lhs.m_value < rhs || lhs == rhs; + } + + friend bool operator >= ( double lhs, Approx const& rhs ) { + return lhs > rhs.m_value || lhs == rhs; + } + + friend bool operator >= ( Approx const& lhs, double rhs ) { + return lhs.m_value > rhs || lhs == rhs; + } + + Approx& epsilon( double newEpsilon ) { + m_epsilon = newEpsilon; + return *this; + } + + Approx& margin( double newMargin ) { + m_margin = newMargin; + return *this; + } + + Approx& scale( double newScale ) { + m_scale = newScale; + return *this; + } +#endif + + std::string toString() const { + std::ostringstream oss; + oss << "Approx( " << Catch::toString( m_value ) << " )"; + return oss.str(); + } + + private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; + }; +} + +template<> +inline std::string toString( Detail::Approx const& value ) { + return value.toString(); +} + +} // end namespace Catch + +// #included from: internal/catch_matchers_string.h +#define TWOBLUECUBES_CATCH_MATCHERS_STRING_H_INCLUDED + +namespace Catch { +namespace Matchers { + + namespace StdString { + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); + std::string adjustString( std::string const& str ) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct StringMatcherBase : MatcherBase { + StringMatcherBase( std::string const& operation, CasedString const& comparator ); + virtual std::string describe() const CATCH_OVERRIDE; + + CasedString m_comparator; + std::string m_operation; + }; + + struct EqualsMatcher : StringMatcherBase { + EqualsMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct ContainsMatcher : StringMatcherBase { + ContainsMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher( CasedString const& comparator ); + virtual bool match( std::string const& source ) const CATCH_OVERRIDE; + }; + + } // namespace StdString + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + +} // namespace Matchers +} // namespace Catch + +// #included from: internal/catch_matchers_vector.h +#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED + +namespace Catch { +namespace Matchers { + + namespace Vector { + + template + struct ContainsElementMatcher : MatcherBase, T> { + + ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + return std::find(v.begin(), v.end(), m_comparator) != v.end(); + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "Contains: " + Catch::toString( m_comparator ); + } + + T const& m_comparator; + }; + + template + struct ContainsMatcher : MatcherBase, std::vector > { + + ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (size_t i = 0; i < m_comparator.size(); ++i) + if (std::find(v.begin(), v.end(), m_comparator[i]) == v.end()) + return false; + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + return "Contains: " + Catch::toString( m_comparator ); + } + + std::vector const& m_comparator; + }; + + template + struct EqualsMatcher : MatcherBase, std::vector > { + + EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const CATCH_OVERRIDE { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + virtual std::string describe() const CATCH_OVERRIDE { + return "Equals: " + Catch::toString( m_comparator ); + } + std::vector const& m_comparator; + }; + + } // namespace Vector + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + template + Vector::ContainsMatcher Contains( std::vector const& comparator ) { + return Vector::ContainsMatcher( comparator ); + } + + template + Vector::ContainsElementMatcher VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher( comparator ); + } + + template + Vector::EqualsMatcher Equals( std::vector const& comparator ) { + return Vector::EqualsMatcher( comparator ); + } + +} // namespace Matchers +} // namespace Catch + +// #included from: internal/catch_interfaces_tag_alias_registry.h +#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED + +// #included from: catch_tag_alias.h +#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED + +#include + +namespace Catch { + + struct TagAlias { + TagAlias( std::string const& _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} + + std::string tag; + SourceLineInfo lineInfo; + }; + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } +// #included from: catch_option.hpp +#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED + +namespace Catch { + + // An optional type + template + class Option { + public: + Option() : nullableValue( CATCH_NULL ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = CATCH_NULL; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != CATCH_NULL; } + bool none() const { return nullableValue == CATCH_NULL; } + + bool operator !() const { return nullableValue == CATCH_NULL; } + operator SafeBool::type() const { + return SafeBool::makeSafe( some() ); + } + + private: + T *nullableValue; + union { + char storage[sizeof(T)]; + + // These are here to force alignment for the storage + long double dummy1; + void (*dummy2)(); + long double dummy3; +#ifdef CATCH_CONFIG_CPP11_LONG_LONG + long long dummy4; +#endif + }; + }; + +} // end namespace Catch + +namespace Catch { + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + virtual Option find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// #included from: internal/catch_test_case_info.h +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED + +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestCase; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ); + + TestCaseInfo( TestCaseInfo const& other ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string name; + std::string className; + std::string description; + std::set tags; + std::set lcaseTags; + std::string tagsAsString; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestCase* testCase, TestCaseInfo const& info ); + TestCase( TestCase const& other ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + void swap( TestCase& other ); + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + TestCase& operator = ( TestCase const& other ); + + private: + Ptr test; + }; + + TestCase makeTestCase( ITestCase* testCase, + std::string const& className, + std::string const& name, + std::string const& description, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + +#ifdef __OBJC__ +// #included from: internal/catch_objc.hpp +#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED + +#import + +#include + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public SharedImpl { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline size_t registerTestMethods() { + size_t noTestMethods = 0; + int noClasses = objc_getClassList( CATCH_NULL, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + struct StringHolder : MatcherBase{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + virtual bool match( NSString* arg ) const CATCH_OVERRIDE { + return false; + } + + NSString* m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( NSString* str ) const CATCH_OVERRIDE { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "equals string: " + Catch::toString( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( NSString* str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "contains string: " + Catch::toString( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( NSString* str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "starts with: " + Catch::toString( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + virtual bool match( NSString* str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + virtual std::string describe() const CATCH_OVERRIDE { + return "ends with: " + Catch::toString( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_TEST_CASE( name, desc )\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ +{\ +return @ name; \ +}\ ++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ +{ \ +return @ desc; \ +} \ +-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) + +#endif + +#ifdef CATCH_IMPL + +// !TBD: Move the leak detector code into a separate header +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include +class LeakDetector { +public: + LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +}; +#else +class LeakDetector {}; +#endif + +LeakDetector leakDetector; + +// #included from: internal/catch_impl.hpp +#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED + +// Collect all the implementation files together here +// These are the equivalent of what would usually be cpp files + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// #included from: ../catch_session.hpp +#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED + +// #included from: internal/catch_commandline.hpp +#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED + +// #included from: catch_config.hpp +#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED + +// #included from: catch_test_spec_parser.hpp +#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// #included from: catch_test_spec.hpp +#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// #included from: catch_wildcard_pattern.hpp +#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED + +#include + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_wildcard( NoWildcard ), + m_pattern( adjustCase( pattern ) ) + { + if( startsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); + } + } + virtual ~WildcardPattern(); + virtual bool matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == adjustCase( str ); + case WildcardAtStart: + return endsWith( adjustCase( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( adjustCase( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( adjustCase( str ), m_pattern ); + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" +#endif + throw std::logic_error( "Unknown enum" ); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + } + private: + std::string adjustCase( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; + } + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard; + std::string m_pattern; + }; +} + +#include +#include + +namespace Catch { + + class TestSpec { + struct Pattern : SharedImpl<> { + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + }; + class NamePattern : public Pattern { + public: + NamePattern( std::string const& name ) + : m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + virtual ~NamePattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( toLower( testCase.name ) ); + } + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} + virtual ~TagPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { + return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); + } + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} + virtual ~ExcludedPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } + private: + Ptr m_underlyingPattern; + }; + + struct Filter { + std::vector > m_patterns; + + bool matches( TestCaseInfo const& testCase ) const { + // All patterns in a filter must match for the filter to be a match + for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { + if( !(*it)->matches( testCase ) ) + return false; + } + return true; + } + }; + + public: + bool hasFilters() const { + return !m_filters.empty(); + } + bool matches( TestCaseInfo const& testCase ) const { + // A TestSpec matches if any filter matches + for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) + if( it->matches( testCase ) ) + return true; + return false; + } + + private: + std::vector m_filters; + + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode; + bool m_exclusion; + std::size_t m_start, m_pos; + std::string m_arg; + std::vector m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ) :m_mode(None), m_exclusion(false), m_start(0), m_pos(0), m_tagAliases( &tagAliases ) {} + + TestSpecParser& parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases( arg ); + m_escapeChars.clear(); + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + visitChar( m_arg[m_pos] ); + if( m_mode == Name ) + addPattern(); + return *this; + } + TestSpec testSpec() { + addFilter(); + return m_testSpec; + } + private: + void visitChar( char c ) { + if( m_mode == None ) { + switch( c ) { + case ' ': return; + case '~': m_exclusion = true; return; + case '[': return startNewMode( Tag, ++m_pos ); + case '"': return startNewMode( QuotedName, ++m_pos ); + case '\\': return escape(); + default: startNewMode( Name, m_pos ); break; + } + } + if( m_mode == Name ) { + if( c == ',' ) { + addPattern(); + addFilter(); + } + else if( c == '[' ) { + if( subString() == "exclude:" ) + m_exclusion = true; + else + addPattern(); + startNewMode( Tag, ++m_pos ); + } + else if( c == '\\' ) + escape(); + } + else if( m_mode == EscapedName ) + m_mode = Name; + else if( m_mode == QuotedName && c == '"' ) + addPattern(); + else if( m_mode == Tag && c == ']' ) + addPattern(); + } + void startNewMode( Mode mode, std::size_t start ) { + m_mode = mode; + m_start = start; + } + void escape() { + if( m_mode == None ) + m_start = m_pos; + m_mode = EscapedName; + m_escapeChars.push_back( m_pos ); + } + std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } + template + void addPattern() { + std::string token = subString(); + for( size_t i = 0; i < m_escapeChars.size(); ++i ) + token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); + m_escapeChars.clear(); + if( startsWith( token, "exclude:" ) ) { + m_exclusion = true; + token = token.substr( 8 ); + } + if( !token.empty() ) { + Ptr pattern = new T( token ); + if( m_exclusion ) + pattern = new TestSpec::ExcludedPattern( pattern ); + m_currentFilter.m_patterns.push_back( pattern ); + } + m_exclusion = false; + m_mode = None; + } + void addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + }; + inline TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// #included from: catch_interfaces_config.h +#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct Verbosity { enum Level { + NoOutput = 0, + Quiet, + Normal + }; }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + struct WaitForKeypress { enum When { + Never, + BeforeStart = 1, + BeforeExit = 2, + BeforeStartAndExit = BeforeStart | BeforeExit + }; }; + + class TestSpec; + + struct IConfig : IShared { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector const& getSectionsToRun() const = 0; + + }; +} + +// #included from: catch_stream.h +#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED + +// #included from: catch_streambuf.h +#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED + +#include + +namespace Catch { + + class StreamBufBase : public std::streambuf { + public: + virtual ~StreamBufBase() CATCH_NOEXCEPT; + }; +} + +#include +#include +#include +#include + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + std::ostream& clog(); + + struct IStream { + virtual ~IStream() CATCH_NOEXCEPT; + virtual std::ostream& stream() const = 0; + }; + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( std::string const& filename ); + virtual ~FileStream() CATCH_NOEXCEPT; + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + CoutStream(); + virtual ~CoutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; + + class DebugOutStream : public IStream { + CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream(); + virtual ~DebugOutStream() CATCH_NOEXCEPT; + + public: // IStream + virtual std::ostream& stream() const CATCH_OVERRIDE; + }; +} + +#include +#include +#include +#include + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct ConfigData { + + ConfigData() + : listTests( false ), + listTags( false ), + listReporters( false ), + listTestNamesOnly( false ), + listExtraInfo( false ), + showSuccessfulTests( false ), + shouldDebugBreak( false ), + noThrow( false ), + showHelp( false ), + showInvisibles( false ), + filenamesAsTags( false ), + libIdentify( false ), + abortAfter( -1 ), + rngSeed( 0 ), + verbosity( Verbosity::Normal ), + warnings( WarnAbout::Nothing ), + showDurations( ShowDurations::DefaultForReporter ), + runOrder( RunTests::InDeclarationOrder ), + useColour( UseColour::Auto ), + waitForKeypress( WaitForKeypress::Never ) + {} + + bool listTests; + bool listTags; + bool listReporters; + bool listTestNamesOnly; + bool listExtraInfo; + + bool showSuccessfulTests; + bool shouldDebugBreak; + bool noThrow; + bool showHelp; + bool showInvisibles; + bool filenamesAsTags; + bool libIdentify; + + int abortAfter; + unsigned int rngSeed; + + Verbosity::Level verbosity; + WarnAbout::What warnings; + ShowDurations::OrNot showDurations; + RunTests::InWhatOrder runOrder; + UseColour::YesOrNo useColour; + WaitForKeypress::When waitForKeypress; + + std::string outputFilename; + std::string name; + std::string processName; + + std::vector reporterNames; + std::vector testsOrTags; + std::vector sectionsToRun; + }; + + class Config : public SharedImpl { + private: + Config( Config const& other ); + Config& operator = ( Config const& other ); + virtual void dummy(); + public: + + Config() + {} + + Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + if( !data.testsOrTags.empty() ) { + TestSpecParser parser( ITagAliasRegistry::get() ); + for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) + parser.parse( data.testsOrTags[i] ); + m_testSpec = parser.testSpec(); + } + } + + virtual ~Config() {} + + std::string const& getFilename() const { + return m_data.outputFilename ; + } + + bool listTests() const { return m_data.listTests; } + bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool listTags() const { return m_data.listTags; } + bool listReporters() const { return m_data.listReporters; } + bool listExtraInfo() const { return m_data.listExtraInfo; } + + std::string getProcessName() const { return m_data.processName; } + + std::vector const& getReporterNames() const { return m_data.reporterNames; } + std::vector const& getSectionsToRun() const CATCH_OVERRIDE { return m_data.sectionsToRun; } + + virtual TestSpec const& testSpec() const CATCH_OVERRIDE { return m_testSpec; } + + bool showHelp() const { return m_data.showHelp; } + + // IConfig interface + virtual bool allowThrows() const CATCH_OVERRIDE { return !m_data.noThrow; } + virtual std::ostream& stream() const CATCH_OVERRIDE { return m_stream->stream(); } + virtual std::string name() const CATCH_OVERRIDE { return m_data.name.empty() ? m_data.processName : m_data.name; } + virtual bool includeSuccessfulResults() const CATCH_OVERRIDE { return m_data.showSuccessfulTests; } + virtual bool warnAboutMissingAssertions() const CATCH_OVERRIDE { return m_data.warnings & WarnAbout::NoAssertions; } + virtual ShowDurations::OrNot showDurations() const CATCH_OVERRIDE { return m_data.showDurations; } + virtual RunTests::InWhatOrder runOrder() const CATCH_OVERRIDE { return m_data.runOrder; } + virtual unsigned int rngSeed() const CATCH_OVERRIDE { return m_data.rngSeed; } + virtual UseColour::YesOrNo useColour() const CATCH_OVERRIDE { return m_data.useColour; } + virtual bool shouldDebugBreak() const CATCH_OVERRIDE { return m_data.shouldDebugBreak; } + virtual int abortAfter() const CATCH_OVERRIDE { return m_data.abortAfter; } + virtual bool showInvisibles() const CATCH_OVERRIDE { return m_data.showInvisibles; } + + private: + + IStream const* openStream() { + if( m_data.outputFilename.empty() ) + return new CoutStream(); + else if( m_data.outputFilename[0] == '%' ) { + if( m_data.outputFilename == "%debug" ) + return new DebugOutStream(); + else + throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); + } + else + return new FileStream( m_data.outputFilename ); + } + ConfigData m_data; + + CATCH_AUTO_PTR( IStream const ) m_stream; + TestSpec m_testSpec; + }; + +} // end namespace Catch + +// #included from: catch_clara.h +#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH +#undef CLARA_CONFIG_CONSOLE_WIDTH +#endif +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +// Declare Clara inside the Catch namespace +#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { +// #included from: ../external/clara.h + +// Version 0.0.2.4 + +// Only use header guard if we are not using an outer namespace +#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) + +#ifndef STITCH_CLARA_OPEN_NAMESPACE +#define TWOBLUECUBES_CLARA_H_INCLUDED +#define STITCH_CLARA_OPEN_NAMESPACE +#define STITCH_CLARA_CLOSE_NAMESPACE +#else +#define STITCH_CLARA_CLOSE_NAMESPACE } +#endif + +#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE + +// ----------- #included from tbc_text_format.h ----------- + +// Only use header guard if we are not using an outer namespace +#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) +#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +#define TBC_TEXT_FORMAT_H_INCLUDED +#endif + +#include +#include +#include +#include +#include + +// Use optional outer namespace +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ), + tabChar( '\t' ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + char tabChar; // If this char is seen the indent is changed to current pos + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + std::string wrappableChars = " [({.,/|\\-"; + std::size_t indent = _attr.initialIndent != std::string::npos + ? _attr.initialIndent + : _attr.indent; + std::string remainder = _str; + + while( !remainder.empty() ) { + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + std::size_t tabPos = std::string::npos; + std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); + std::size_t pos = remainder.find_first_of( '\n' ); + if( pos <= width ) { + width = pos; + } + pos = remainder.find_last_of( _attr.tabChar, width ); + if( pos != std::string::npos ) { + tabPos = pos; + if( remainder[width] == '\n' ) + width--; + remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); + } + + if( width == remainder.size() ) { + spliceLine( indent, remainder, width ); + } + else if( remainder[width] == '\n' ) { + spliceLine( indent, remainder, width ); + if( width <= 1 || remainder.size() != 1 ) + remainder = remainder.substr( 1 ); + indent = _attr.indent; + } + else { + pos = remainder.find_last_of( wrappableChars, width ); + if( pos != std::string::npos && pos > 0 ) { + spliceLine( indent, remainder, pos ); + if( remainder[0] == ' ' ) + remainder = remainder.substr( 1 ); + } + else { + spliceLine( indent, remainder, width-1 ); + lines.back() += "-"; + } + if( lines.size() == 1 ) + indent = _attr.indent; + if( tabPos != std::string::npos ) + indent += tabPos; + } + } + } + + void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { + lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); + _remainder = _remainder.substr( _pos ); + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TBC_TEXT_FORMAT_H_INCLUDED + +// ----------- end of #include from tbc_text_format.h ----------- +// ........... back in clara.h + +#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE + +// ----------- #included from clara_compilers.h ----------- + +#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED +#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// The following features are defined: +// +// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? +// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? +// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods +// CLARA_CONFIG_CPP11_OVERRIDE : is override supported? +// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) + +// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? + +// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? + +// In general each macro has a _NO_ form +// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 + +#ifdef __clang__ + +#if __has_feature(cxx_nullptr) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#if __has_feature(cxx_noexcept) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// GCC +#ifdef __GNUC__ + +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +// - otherwise more recent versions define __cplusplus >= 201103L +// and will get picked up below + +#endif // __GNUC__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#if (_MSC_VER >= 1600) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// C++ language feature support + +// catch all support for C++11 +#if defined(__cplusplus) && __cplusplus >= 201103L + +#define CLARA_CPP11_OR_GREATER + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) +#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT +#endif + +#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +#endif + +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) +#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE +#endif +#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) +#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR +#endif + +#endif // __cplusplus >= 201103L + +// Now set the actual defines based on the above + anything the user has configured +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NULLPTR +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_OVERRIDE +#endif +#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) +#define CLARA_CONFIG_CPP11_UNIQUE_PTR +#endif + +// noexcept support: +#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) +#define CLARA_NOEXCEPT noexcept +# define CLARA_NOEXCEPT_IS(x) noexcept(x) +#else +#define CLARA_NOEXCEPT throw() +# define CLARA_NOEXCEPT_IS(x) +#endif + +// nullptr support +#ifdef CLARA_CONFIG_CPP11_NULLPTR +#define CLARA_NULL nullptr +#else +#define CLARA_NULL NULL +#endif + +// override support +#ifdef CLARA_CONFIG_CPP11_OVERRIDE +#define CLARA_OVERRIDE override +#else +#define CLARA_OVERRIDE +#endif + +// unique_ptr support +#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR +# define CLARA_AUTO_PTR( T ) std::unique_ptr +#else +# define CLARA_AUTO_PTR( T ) std::auto_ptr +#endif + +#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED + +// ----------- end of #include from clara_compilers.h ----------- +// ........... back in clara.h + +#include +#include +#include + +#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) +#define CLARA_PLATFORM_WINDOWS +#endif + +// Use optional outer namespace +#ifdef STITCH_CLARA_OPEN_NAMESPACE +STITCH_CLARA_OPEN_NAMESPACE +#endif + +namespace Clara { + + struct UnpositionalTag {}; + + extern UnpositionalTag _; + +#ifdef CLARA_CONFIG_MAIN + UnpositionalTag _; +#endif + + namespace Detail { + +#ifdef CLARA_CONSOLE_WIDTH + const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + using namespace Tbc; + + inline bool startsWith( std::string const& str, std::string const& prefix ) { + return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; + } + + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + template struct RemoveConstRef{ typedef T type; }; + + template struct IsBool { static const bool value = false; }; + template<> struct IsBool { static const bool value = true; }; + + template + void convertInto( std::string const& _source, T& _dest ) { + std::stringstream ss; + ss << _source; + ss >> _dest; + if( ss.fail() ) + throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); + } + inline void convertInto( std::string const& _source, std::string& _dest ) { + _dest = _source; + } + char toLowerCh(char c) { + return static_cast( std::tolower( c ) ); + } + inline void convertInto( std::string const& _source, bool& _dest ) { + std::string sourceLC = _source; + std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); + if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) + _dest = true; + else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) + _dest = false; + else + throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); + } + + template + struct IArgFunction { + virtual ~IArgFunction() {} +#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS + IArgFunction() = default; + IArgFunction( IArgFunction const& ) = default; +#endif + virtual void set( ConfigT& config, std::string const& value ) const = 0; + virtual bool takesArg() const = 0; + virtual IArgFunction* clone() const = 0; + }; + + template + class BoundArgFunction { + public: + BoundArgFunction() : functionObj( CLARA_NULL ) {} + BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} + BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} + BoundArgFunction& operator = ( BoundArgFunction const& other ) { + IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; + delete functionObj; + functionObj = newFunctionObj; + return *this; + } + ~BoundArgFunction() { delete functionObj; } + + void set( ConfigT& config, std::string const& value ) const { + functionObj->set( config, value ); + } + bool takesArg() const { return functionObj->takesArg(); } + + bool isSet() const { + return functionObj != CLARA_NULL; + } + private: + IArgFunction* functionObj; + }; + + template + struct NullBinder : IArgFunction{ + virtual void set( C&, std::string const& ) const {} + virtual bool takesArg() const { return true; } + virtual IArgFunction* clone() const { return new NullBinder( *this ); } + }; + + template + struct BoundDataMember : IArgFunction{ + BoundDataMember( M C::* _member ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + convertInto( stringValue, p.*member ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } + M C::* member; + }; + template + struct BoundUnaryMethod : IArgFunction{ + BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + (p.*member)( value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } + void (C::*member)( M ); + }; + template + struct BoundNullaryMethod : IArgFunction{ + BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} + virtual void set( C& p, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + (p.*member)(); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } + void (C::*member)(); + }; + + template + struct BoundUnaryFunction : IArgFunction{ + BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + bool value; + convertInto( stringValue, value ); + if( value ) + function( obj ); + } + virtual bool takesArg() const { return false; } + virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } + void (*function)( C& ); + }; + + template + struct BoundBinaryFunction : IArgFunction{ + BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} + virtual void set( C& obj, std::string const& stringValue ) const { + typename RemoveConstRef::type value; + convertInto( stringValue, value ); + function( obj, value ); + } + virtual bool takesArg() const { return !IsBool::value; } + virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } + void (*function)( C&, T ); + }; + + } // namespace Detail + + inline std::vector argsToVector( int argc, char const* const* const argv ) { + std::vector args( static_cast( argc ) ); + for( std::size_t i = 0; i < static_cast( argc ); ++i ) + args[i] = argv[i]; + + return args; + } + + class Parser { + enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; + Mode mode; + std::size_t from; + bool inQuotes; + public: + + struct Token { + enum Type { Positional, ShortOpt, LongOpt }; + Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} + Type type; + std::string data; + }; + + Parser() : mode( None ), from( 0 ), inQuotes( false ){} + + void parseIntoTokens( std::vector const& args, std::vector& tokens ) { + const std::string doubleDash = "--"; + for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) + parseIntoTokens( args[i], tokens); + } + + void parseIntoTokens( std::string const& arg, std::vector& tokens ) { + for( std::size_t i = 0; i < arg.size(); ++i ) { + char c = arg[i]; + if( c == '"' ) + inQuotes = !inQuotes; + mode = handleMode( i, c, arg, tokens ); + } + mode = handleMode( arg.size(), '\0', arg, tokens ); + } + Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + switch( mode ) { + case None: return handleNone( i, c ); + case MaybeShortOpt: return handleMaybeShortOpt( i, c ); + case ShortOpt: + case LongOpt: + case SlashOpt: return handleOpt( i, c, arg, tokens ); + case Positional: return handlePositional( i, c, arg, tokens ); + default: throw std::logic_error( "Unknown mode" ); + } + } + + Mode handleNone( std::size_t i, char c ) { + if( inQuotes ) { + from = i; + return Positional; + } + switch( c ) { + case '-': return MaybeShortOpt; +#ifdef CLARA_PLATFORM_WINDOWS + case '/': from = i+1; return SlashOpt; +#endif + default: from = i; return Positional; + } + } + Mode handleMaybeShortOpt( std::size_t i, char c ) { + switch( c ) { + case '-': from = i+1; return LongOpt; + default: from = i; return ShortOpt; + } + } + + Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) + return mode; + + std::string optName = arg.substr( from, i-from ); + if( mode == ShortOpt ) + for( std::size_t j = 0; j < optName.size(); ++j ) + tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); + else if( mode == SlashOpt && optName.size() == 1 ) + tokens.push_back( Token( Token::ShortOpt, optName ) ); + else + tokens.push_back( Token( Token::LongOpt, optName ) ); + return None; + } + Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { + if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) + return mode; + + std::string data = arg.substr( from, i-from ); + tokens.push_back( Token( Token::Positional, data ) ); + return None; + } + }; + + template + struct CommonArgProperties { + CommonArgProperties() {} + CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} + + Detail::BoundArgFunction boundField; + std::string description; + std::string detail; + std::string placeholder; // Only value if boundField takes an arg + + bool takesArg() const { + return !placeholder.empty(); + } + void validate() const { + if( !boundField.isSet() ) + throw std::logic_error( "option not bound" ); + } + }; + struct OptionArgProperties { + std::vector shortNames; + std::string longName; + + bool hasShortName( std::string const& shortName ) const { + return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); + } + bool hasLongName( std::string const& _longName ) const { + return _longName == longName; + } + }; + struct PositionalArgProperties { + PositionalArgProperties() : position( -1 ) {} + int position; // -1 means non-positional (floating) + + bool isFixedPositional() const { + return position != -1; + } + }; + + template + class CommandLine { + + struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { + Arg() {} + Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} + + using CommonArgProperties::placeholder; // !TBD + + std::string dbgName() const { + if( !longName.empty() ) + return "--" + longName; + if( !shortNames.empty() ) + return "-" + shortNames[0]; + return "positional args"; + } + std::string commands() const { + std::ostringstream oss; + bool first = true; + std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); + for(; it != itEnd; ++it ) { + if( first ) + first = false; + else + oss << ", "; + oss << "-" << *it; + } + if( !longName.empty() ) { + if( !first ) + oss << ", "; + oss << "--" << longName; + } + if( !placeholder.empty() ) + oss << " <" << placeholder << ">"; + return oss.str(); + } + }; + + typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; + + friend void addOptName( Arg& arg, std::string const& optName ) + { + if( optName.empty() ) + return; + if( Detail::startsWith( optName, "--" ) ) { + if( !arg.longName.empty() ) + throw std::logic_error( "Only one long opt may be specified. '" + + arg.longName + + "' already specified, now attempting to add '" + + optName + "'" ); + arg.longName = optName.substr( 2 ); + } + else if( Detail::startsWith( optName, "-" ) ) + arg.shortNames.push_back( optName.substr( 1 ) ); + else + throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); + } + friend void setPositionalArg( Arg& arg, int position ) + { + arg.position = position; + } + + class ArgBuilder { + public: + ArgBuilder( Arg* arg ) : m_arg( arg ) {} + + // Bind a non-boolean data member (requires placeholder string) + template + void bind( M C::* field, std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + m_arg->placeholder = placeholder; + } + // Bind a boolean data member (no placeholder required) + template + void bind( bool C::* field ) { + m_arg->boundField = new Detail::BoundDataMember( field ); + } + + // Bind a method taking a single, non-boolean argument (requires a placeholder string) + template + void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + m_arg->placeholder = placeholder; + } + + // Bind a method taking a single, boolean argument (no placeholder string required) + template + void bind( void (C::* unaryMethod)( bool ) ) { + m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); + } + + // Bind a method that takes no arguments (will be called if opt is present) + template + void bind( void (C::* nullaryMethod)() ) { + m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); + } + + // Bind a free function taking a single argument - the object to operate on (no placeholder string required) + template + void bind( void (* unaryFunction)( C& ) ) { + m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); + } + + // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) + template + void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { + m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); + m_arg->placeholder = placeholder; + } + + ArgBuilder& describe( std::string const& description ) { + m_arg->description = description; + return *this; + } + ArgBuilder& detail( std::string const& detail ) { + m_arg->detail = detail; + return *this; + } + + protected: + Arg* m_arg; + }; + + class OptBuilder : public ArgBuilder { + public: + OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} + OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} + + OptBuilder& operator[]( std::string const& optName ) { + addOptName( *ArgBuilder::m_arg, optName ); + return *this; + } + }; + + public: + + CommandLine() + : m_boundProcessName( new Detail::NullBinder() ), + m_highestSpecifiedArgPosition( 0 ), + m_throwOnUnrecognisedTokens( false ) + {} + CommandLine( CommandLine const& other ) + : m_boundProcessName( other.m_boundProcessName ), + m_options ( other.m_options ), + m_positionalArgs( other.m_positionalArgs ), + m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), + m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) + { + if( other.m_floatingArg.get() ) + m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); + } + + CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { + m_throwOnUnrecognisedTokens = shouldThrow; + return *this; + } + + OptBuilder operator[]( std::string const& optName ) { + m_options.push_back( Arg() ); + addOptName( m_options.back(), optName ); + OptBuilder builder( &m_options.back() ); + return builder; + } + + ArgBuilder operator[]( int position ) { + m_positionalArgs.insert( std::make_pair( position, Arg() ) ); + if( position > m_highestSpecifiedArgPosition ) + m_highestSpecifiedArgPosition = position; + setPositionalArg( m_positionalArgs[position], position ); + ArgBuilder builder( &m_positionalArgs[position] ); + return builder; + } + + // Invoke this with the _ instance + ArgBuilder operator[]( UnpositionalTag ) { + if( m_floatingArg.get() ) + throw std::logic_error( "Only one unpositional argument can be added" ); + m_floatingArg.reset( new Arg() ); + ArgBuilder builder( m_floatingArg.get() ); + return builder; + } + + template + void bindProcessName( M C::* field ) { + m_boundProcessName = new Detail::BoundDataMember( field ); + } + template + void bindProcessName( void (C::*_unaryMethod)( M ) ) { + m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); + } + + void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { + typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; + std::size_t maxWidth = 0; + for( it = itBegin; it != itEnd; ++it ) + maxWidth = (std::max)( maxWidth, it->commands().size() ); + + for( it = itBegin; it != itEnd; ++it ) { + Detail::Text usage( it->commands(), Detail::TextAttributes() + .setWidth( maxWidth+indent ) + .setIndent( indent ) ); + Detail::Text desc( it->description, Detail::TextAttributes() + .setWidth( width - maxWidth - 3 ) ); + + for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { + std::string usageCol = i < usage.size() ? usage[i] : ""; + os << usageCol; + + if( i < desc.size() && !desc[i].empty() ) + os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) + << desc[i]; + os << "\n"; + } + } + } + std::string optUsage() const { + std::ostringstream oss; + optUsage( oss ); + return oss.str(); + } + + void argSynopsis( std::ostream& os ) const { + for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { + if( i > 1 ) + os << " "; + typename std::map::const_iterator it = m_positionalArgs.find( i ); + if( it != m_positionalArgs.end() ) + os << "<" << it->second.placeholder << ">"; + else if( m_floatingArg.get() ) + os << "<" << m_floatingArg->placeholder << ">"; + else + throw std::logic_error( "non consecutive positional arguments with no floating args" ); + } + // !TBD No indication of mandatory args + if( m_floatingArg.get() ) { + if( m_highestSpecifiedArgPosition > 1 ) + os << " "; + os << "[<" << m_floatingArg->placeholder << "> ...]"; + } + } + std::string argSynopsis() const { + std::ostringstream oss; + argSynopsis( oss ); + return oss.str(); + } + + void usage( std::ostream& os, std::string const& procName ) const { + validate(); + os << "usage:\n " << procName << " "; + argSynopsis( os ); + if( !m_options.empty() ) { + os << " [options]\n\nwhere options are: \n"; + optUsage( os, 2 ); + } + os << "\n"; + } + std::string usage( std::string const& procName ) const { + std::ostringstream oss; + usage( oss, procName ); + return oss.str(); + } + + ConfigT parse( std::vector const& args ) const { + ConfigT config; + parseInto( args, config ); + return config; + } + + std::vector parseInto( std::vector const& args, ConfigT& config ) const { + std::string processName = args.empty() ? std::string() : args[0]; + std::size_t lastSlash = processName.find_last_of( "/\\" ); + if( lastSlash != std::string::npos ) + processName = processName.substr( lastSlash+1 ); + m_boundProcessName.set( config, processName ); + std::vector tokens; + Parser parser; + parser.parseIntoTokens( args, tokens ); + return populate( tokens, config ); + } + + std::vector populate( std::vector const& tokens, ConfigT& config ) const { + validate(); + std::vector unusedTokens = populateOptions( tokens, config ); + unusedTokens = populateFixedArgs( unusedTokens, config ); + unusedTokens = populateFloatingArgs( unusedTokens, config ); + return unusedTokens; + } + + std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + std::vector errors; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); + for(; it != itEnd; ++it ) { + Arg const& arg = *it; + + try { + if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || + ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { + if( arg.takesArg() ) { + if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) + errors.push_back( "Expected argument to option: " + token.data ); + else + arg.boundField.set( config, tokens[++i].data ); + } + else { + arg.boundField.set( config, "true" ); + } + break; + } + } + catch( std::exception& ex ) { + errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); + } + } + if( it == itEnd ) { + if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) + unusedTokens.push_back( token ); + else if( errors.empty() && m_throwOnUnrecognisedTokens ) + errors.push_back( "unrecognised option: " + token.data ); + } + } + if( !errors.empty() ) { + std::ostringstream oss; + for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); + it != itEnd; + ++it ) { + if( it != errors.begin() ) + oss << "\n"; + oss << *it; + } + throw std::runtime_error( oss.str() ); + } + return unusedTokens; + } + std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { + std::vector unusedTokens; + int position = 1; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + typename std::map::const_iterator it = m_positionalArgs.find( position ); + if( it != m_positionalArgs.end() ) + it->second.boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + if( token.type == Parser::Token::Positional ) + position++; + } + return unusedTokens; + } + std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { + if( !m_floatingArg.get() ) + return tokens; + std::vector unusedTokens; + for( std::size_t i = 0; i < tokens.size(); ++i ) { + Parser::Token const& token = tokens[i]; + if( token.type == Parser::Token::Positional ) + m_floatingArg->boundField.set( config, token.data ); + else + unusedTokens.push_back( token ); + } + return unusedTokens; + } + + void validate() const + { + if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) + throw std::logic_error( "No options or arguments specified" ); + + for( typename std::vector::const_iterator it = m_options.begin(), + itEnd = m_options.end(); + it != itEnd; ++it ) + it->validate(); + } + + private: + Detail::BoundArgFunction m_boundProcessName; + std::vector m_options; + std::map m_positionalArgs; + ArgAutoPtr m_floatingArg; + int m_highestSpecifiedArgPosition; + bool m_throwOnUnrecognisedTokens; + }; + +} // end namespace Clara + +STITCH_CLARA_CLOSE_NAMESPACE +#undef STITCH_CLARA_OPEN_NAMESPACE +#undef STITCH_CLARA_CLOSE_NAMESPACE + +#endif // TWOBLUECUBES_CLARA_H_INCLUDED +#undef STITCH_CLARA_OPEN_NAMESPACE + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#include +#include + +namespace Catch { + + inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } + inline void abortAfterX( ConfigData& config, int x ) { + if( x < 1 ) + throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); + config.abortAfter = x; + } + inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } + inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } + inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } + + inline void addWarning( ConfigData& config, std::string const& _warning ) { + if( _warning == "NoAssertions" ) + config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); + else + throw std::runtime_error( "Unrecognised warning: '" + _warning + '\'' ); + } + inline void setOrder( ConfigData& config, std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + throw std::runtime_error( "Unrecognised ordering: '" + order + '\'' ); + } + inline void setRngSeed( ConfigData& config, std::string const& seed ) { + if( seed == "time" ) { + config.rngSeed = static_cast( std::time(0) ); + } + else { + std::stringstream ss; + ss << seed; + ss >> config.rngSeed; + if( ss.fail() ) + throw std::runtime_error( "Argument to --rng-seed should be the word 'time' or a number" ); + } + } + inline void setVerbosity( ConfigData& config, int level ) { + // !TBD: accept strings? + config.verbosity = static_cast( level ); + } + inline void setShowDurations( ConfigData& config, bool _showDurations ) { + config.showDurations = _showDurations + ? ShowDurations::Always + : ShowDurations::Never; + } + inline void setUseColour( ConfigData& config, std::string const& value ) { + std::string mode = toLower( value ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); + } + inline void setWaitForKeypress( ConfigData& config, std::string const& keypress ) { + std::string keypressLc = toLower( keypress ); + if( keypressLc == "start" ) + config.waitForKeypress = WaitForKeypress::BeforeStart; + else if( keypressLc == "exit" ) + config.waitForKeypress = WaitForKeypress::BeforeExit; + else if( keypressLc == "both" ) + config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; + else + throw std::runtime_error( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); + }; + + inline void forceColour( ConfigData& config ) { + config.useColour = UseColour::Yes; + } + inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { + std::ifstream f( _filename.c_str() ); + if( !f.is_open() ) + throw std::domain_error( "Unable to load input file: " + _filename ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) + line = '"' + line + '"'; + addTestOrTags( config, line + ',' ); + } + } + } + + inline Clara::CommandLine makeCommandLineParser() { + + using namespace Clara; + CommandLine cli; + + cli.bindProcessName( &ConfigData::processName ); + + cli["-?"]["-h"]["--help"] + .describe( "display usage information" ) + .bind( &ConfigData::showHelp ); + + cli["-l"]["--list-tests"] + .describe( "list all/matching test cases" ) + .bind( &ConfigData::listTests ); + + cli["-t"]["--list-tags"] + .describe( "list all/matching tags" ) + .bind( &ConfigData::listTags ); + + cli["-s"]["--success"] + .describe( "include successful tests in output" ) + .bind( &ConfigData::showSuccessfulTests ); + + cli["-b"]["--break"] + .describe( "break into debugger on failure" ) + .bind( &ConfigData::shouldDebugBreak ); + + cli["-e"]["--nothrow"] + .describe( "skip exception tests" ) + .bind( &ConfigData::noThrow ); + + cli["-i"]["--invisibles"] + .describe( "show invisibles (tabs, newlines)" ) + .bind( &ConfigData::showInvisibles ); + + cli["-o"]["--out"] + .describe( "output filename" ) + .bind( &ConfigData::outputFilename, "filename" ); + + cli["-r"]["--reporter"] +// .placeholder( "name[:filename]" ) + .describe( "reporter to use (defaults to console)" ) + .bind( &addReporterName, "name" ); + + cli["-n"]["--name"] + .describe( "suite name" ) + .bind( &ConfigData::name, "name" ); + + cli["-a"]["--abort"] + .describe( "abort at first failure" ) + .bind( &abortAfterFirst ); + + cli["-x"]["--abortx"] + .describe( "abort after x failures" ) + .bind( &abortAfterX, "no. failures" ); + + cli["-w"]["--warn"] + .describe( "enable warnings" ) + .bind( &addWarning, "warning name" ); + +// - needs updating if reinstated +// cli.into( &setVerbosity ) +// .describe( "level of verbosity (0=no output)" ) +// .shortOpt( "v") +// .longOpt( "verbosity" ) +// .placeholder( "level" ); + + cli[_] + .describe( "which test or tests to use" ) + .bind( &addTestOrTags, "test name, pattern or tags" ); + + cli["-d"]["--durations"] + .describe( "show test durations" ) + .bind( &setShowDurations, "yes|no" ); + + cli["-f"]["--input-file"] + .describe( "load test names to run from a file" ) + .bind( &loadTestNamesFromFile, "filename" ); + + cli["-#"]["--filenames-as-tags"] + .describe( "adds a tag for the filename" ) + .bind( &ConfigData::filenamesAsTags ); + + cli["-c"]["--section"] + .describe( "specify section to run" ) + .bind( &addSectionToRun, "section name" ); + + // Less common commands which don't have a short form + cli["--list-test-names-only"] + .describe( "list all/matching test cases names only" ) + .bind( &ConfigData::listTestNamesOnly ); + + cli["--list-extra-info"] + .describe( "list all/matching test cases with more info" ) + .bind( &ConfigData::listExtraInfo ); + + cli["--list-reporters"] + .describe( "list all reporters" ) + .bind( &ConfigData::listReporters ); + + cli["--order"] + .describe( "test case order (defaults to decl)" ) + .bind( &setOrder, "decl|lex|rand" ); + + cli["--rng-seed"] + .describe( "set a specific seed for random numbers" ) + .bind( &setRngSeed, "'time'|number" ); + + cli["--force-colour"] + .describe( "force colourised output (deprecated)" ) + .bind( &forceColour ); + + cli["--use-colour"] + .describe( "should output be colourised" ) + .bind( &setUseColour, "yes|no" ); + + cli["--libidentify"] + .describe( "report name and version according to libidentify standard" ) + .bind( &ConfigData::libIdentify ); + + cli["--wait-for-keypress"] + .describe( "waits for a keypress before exiting" ) + .bind( &setWaitForKeypress, "start|exit|both" ); + + return cli; + } + +} // end namespace Catch + +// #included from: internal/catch_list.hpp +#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED + +// #included from: catch_text.h +#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED + +#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH + +#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch +// #included from: ../external/tbc_text_format.h +// Only use header guard if we are not using an outer namespace +#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +# endif +# else +# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED +# endif +#endif +#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#include +#include +#include + +// Use optional outer namespace +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { +#endif + +namespace Tbc { + +#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH + const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; +#else + const unsigned int consoleWidth = 80; +#endif + + struct TextAttributes { + TextAttributes() + : initialIndent( std::string::npos ), + indent( 0 ), + width( consoleWidth-1 ) + {} + + TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } + TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } + TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } + + std::size_t initialIndent; // indent of first line, or npos + std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos + std::size_t width; // maximum width of text, including indent. Longer text will wrap + }; + + class Text { + public: + Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) + : attr( _attr ) + { + const std::string wrappableBeforeChars = "[({<\t"; + const std::string wrappableAfterChars = "])}>-,./|\\"; + const std::string wrappableInsteadOfChars = " \n\r"; + std::string indent = _attr.initialIndent != std::string::npos + ? std::string( _attr.initialIndent, ' ' ) + : std::string( _attr.indent, ' ' ); + + typedef std::string::const_iterator iterator; + iterator it = _str.begin(); + const iterator strEnd = _str.end(); + + while( it != strEnd ) { + + if( lines.size() >= 1000 ) { + lines.push_back( "... message truncated due to excessive size" ); + return; + } + + std::string suffix; + std::size_t width = (std::min)( static_cast( strEnd-it ), _attr.width-static_cast( indent.size() ) ); + iterator itEnd = it+width; + iterator itNext = _str.end(); + + iterator itNewLine = std::find( it, itEnd, '\n' ); + if( itNewLine != itEnd ) + itEnd = itNewLine; + + if( itEnd != strEnd ) { + bool foundWrapPoint = false; + iterator findIt = itEnd; + do { + if( wrappableAfterChars.find( *findIt ) != std::string::npos && findIt != itEnd ) { + itEnd = findIt+1; + itNext = findIt+1; + foundWrapPoint = true; + } + else if( findIt > it && wrappableBeforeChars.find( *findIt ) != std::string::npos ) { + itEnd = findIt; + itNext = findIt; + foundWrapPoint = true; + } + else if( wrappableInsteadOfChars.find( *findIt ) != std::string::npos ) { + itNext = findIt+1; + itEnd = findIt; + foundWrapPoint = true; + } + if( findIt == it ) + break; + else + --findIt; + } + while( !foundWrapPoint ); + + if( !foundWrapPoint ) { + // No good wrap char, so we'll break mid word and add a hyphen + --itEnd; + itNext = itEnd; + suffix = "-"; + } + else { + while( itEnd > it && wrappableInsteadOfChars.find( *(itEnd-1) ) != std::string::npos ) + --itEnd; + } + } + lines.push_back( indent + std::string( it, itEnd ) + suffix ); + + if( indent.size() != _attr.indent ) + indent = std::string( _attr.indent, ' ' ); + it = itNext; + } + } + + typedef std::vector::const_iterator const_iterator; + + const_iterator begin() const { return lines.begin(); } + const_iterator end() const { return lines.end(); } + std::string const& last() const { return lines.back(); } + std::size_t size() const { return lines.size(); } + std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } + std::string toString() const { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + + inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { + for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); + it != itEnd; ++it ) { + if( it != _text.begin() ) + _stream << "\n"; + _stream << *it; + } + return _stream; + } + + private: + std::string str; + TextAttributes attr; + std::vector lines; + }; + +} // end namespace Tbc + +#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE +} // end outer namespace +#endif + +#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED +#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE + +namespace Catch { + using Tbc::Text; + using Tbc::TextAttributes; +} + +// #included from: catch_console_colour.hpp +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + + // By intention + FileName = LightGrey, + Warning = Yellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = Yellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour const& other ); + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved; + }; + + inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } + +} // end namespace Catch + +// #included from: catch_interfaces_reporter.h +#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED + +#include +#include +#include + +namespace Catch +{ + struct ReporterConfig { + explicit ReporterConfig( Ptr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& stream() const { return *m_stream; } + Ptr fullConfig() const { return m_fullConfig; } + + private: + std::ostream* m_stream; + Ptr m_fullConfig; + }; + + struct ReporterPreferences { + ReporterPreferences() + : shouldRedirectStdOut( false ) + {} + + bool shouldRedirectStdOut; + }; + + template + struct LazyStat : Option { + LazyStat() : used( false ) {} + LazyStat& operator=( T const& _value ) { + Option::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option::reset(); + used = false; + } + bool used; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ) : name( _name ) {} + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + virtual ~AssertionStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = default; + AssertionStats& operator = ( AssertionStats && ) = default; +# endif + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + virtual ~SectionStats(); +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; +# endif + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + virtual ~TestCaseStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; +# endif + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + virtual ~TestGroupStats(); + +# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; +# endif + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + virtual ~TestRunStats(); + +# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS + TestRunStats( TestRunStats const& _other ) + : runInfo( _other.runInfo ), + totals( _other.totals ), + aborting( _other.aborting ) + {} +# else + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; +# endif + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + class MultipleReporters; + + struct IStreamingReporter : IShared { + virtual ~IStreamingReporter(); + + // Implementing class must also provide the following static method: + // static std::string getDescription(); + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } + }; + + struct IReporterFactory : IShared { + virtual ~IReporterFactory(); + virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + + struct IReporterRegistry { + typedef std::map > FactoryMap; + typedef std::vector > Listeners; + + virtual ~IReporterRegistry(); + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + + Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); + +} + +#include +#include + +namespace Catch { + + inline std::size_t listTests( Config const& config ) { + + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::size_t matchedTests = 0; + TextAttributes nameAttr, descAttr, tagsAttr; + nameAttr.setInitialIndent( 2 ).setIndent( 4 ); + descAttr.setIndent( 4 ); + tagsAttr.setIndent( 6 ); + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; + if( config.listExtraInfo() ) { + Catch::cout() << " " << testCaseInfo.lineInfo << std::endl; + std::string description = testCaseInfo.description; + if( description.empty() ) + description = "(NO DESCRIPTION)"; + Catch::cout() << Text( description, descAttr ) << std::endl; + } + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; + } + + if( !config.testSpec().hasFilters() ) + Catch::cout() << pluralise( matchedTests, "test case" ) << '\n' << std::endl; + else + Catch::cout() << pluralise( matchedTests, "matching test case" ) << '\n' << std::endl; + return matchedTests; + } + + inline std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( !config.testSpec().hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + std::size_t matchedTests = 0; + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + matchedTests++; + TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); + if( startsWith( testCaseInfo.name, '#' ) ) + Catch::cout() << '"' << testCaseInfo.name << '"'; + else + Catch::cout() << testCaseInfo.name; + if ( config.listExtraInfo() ) + Catch::cout() << "\t@" << testCaseInfo.lineInfo; + Catch::cout() << std::endl; + } + return matchedTests; + } + + struct TagInfo { + TagInfo() : count ( 0 ) {} + void add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + std::string all() const { + std::string out; + for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); + it != itEnd; + ++it ) + out += "[" + *it + "]"; + return out; + } + std::set spellings; + std::size_t count; + }; + + inline std::size_t listTags( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.testSpec().hasFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); + } + + std::map tagCounts; + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); + it != itEnd; + ++it ) { + for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), + tagItEnd = it->getTestCaseInfo().tags.end(); + tagIt != tagItEnd; + ++tagIt ) { + std::string tagName = *tagIt; + std::string lcaseTagName = toLower( tagName ); + std::map::iterator countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( std::map::const_iterator countIt = tagCounts.begin(), + countItEnd = tagCounts.end(); + countIt != countItEnd; + ++countIt ) { + std::ostringstream oss; + oss << " " << std::setw(2) << countIt->second.count << " "; + Text wrapper( countIt->second.all(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( oss.str().size() ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); + Catch::cout() << oss.str() << wrapper << '\n'; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; + return tagCounts.size(); + } + + inline std::size_t listReporters( Config const& /*config*/ ) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; + std::size_t maxNameLen = 0; + for(it = itBegin; it != itEnd; ++it ) + maxNameLen = (std::max)( maxNameLen, it->first.size() ); + + for(it = itBegin; it != itEnd; ++it ) { + Text wrapper( it->second->getDescription(), TextAttributes() + .setInitialIndent( 0 ) + .setIndent( 7+maxNameLen ) + .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); + Catch::cout() << " " + << it->first + << ':' + << std::string( maxNameLen - it->first.size() + 2, ' ' ) + << wrapper << '\n'; + } + Catch::cout() << std::endl; + return factories.size(); + } + + inline Option list( Config const& config ) { + Option listedCount; + if( config.listTests() || ( config.listExtraInfo() && !config.listTestNamesOnly() ) ) + listedCount = listedCount.valueOr(0) + listTests( config ); + if( config.listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); + if( config.listTags() ) + listedCount = listedCount.valueOr(0) + listTags( config ); + if( config.listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters( config ); + return listedCount; + } + +} // end namespace Catch + +// #included from: internal/catch_run_context.hpp +#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED + +// #included from: catch_test_case_tracker.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED + +#include +#include +#include +#include +#include + +CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS + +namespace Catch { +namespace TestCaseTracking { + + struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) + : name( _name ), + location( _location ) + {} + }; + + struct ITracker : SharedImpl<> { + virtual ~ITracker(); + + // static queries + virtual NameAndLocation const& nameAndLocation() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( Ptr const& child ) = 0; + virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + Ptr m_rootTracker; + ITracker* m_currentTracker; + RunState m_runState; + + public: + + static TrackerContext& instance() { + static TrackerContext s_instance; + return s_instance; + } + + TrackerContext() + : m_currentTracker( CATCH_NULL ), + m_runState( NotStarted ) + {} + + ITracker& startRun(); + + void endRun() { + m_rootTracker.reset(); + m_currentTracker = CATCH_NULL; + m_runState = NotStarted; + } + + void startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void completeCycle() { + m_runState = CompletedCycle; + } + + bool completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& currentTracker() { + return *m_currentTracker; + } + void setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + class TrackerHasName { + NameAndLocation m_nameAndLocation; + public: + TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} + bool operator ()( Ptr const& tracker ) { + return + tracker->nameAndLocation().name == m_nameAndLocation.name && + tracker->nameAndLocation().location == m_nameAndLocation.location; + } + }; + typedef std::vector > Children; + NameAndLocation m_nameAndLocation; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState; + public: + TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : m_nameAndLocation( nameAndLocation ), + m_ctx( ctx ), + m_parent( parent ), + m_runState( NotStarted ) + {} + virtual ~TrackerBase(); + + virtual NameAndLocation const& nameAndLocation() const CATCH_OVERRIDE { + return m_nameAndLocation; + } + virtual bool isComplete() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { + return m_runState == CompletedSuccessfully; + } + virtual bool isOpen() const CATCH_OVERRIDE { + return m_runState != NotStarted && !isComplete(); + } + virtual bool hasChildren() const CATCH_OVERRIDE { + return !m_children.empty(); + } + + virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { + m_children.push_back( child ); + } + + virtual ITracker* findChild( NameAndLocation const& nameAndLocation ) CATCH_OVERRIDE { + Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); + return( it != m_children.end() ) + ? it->get() + : CATCH_NULL; + } + virtual ITracker& parent() CATCH_OVERRIDE { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + virtual void openChild() CATCH_OVERRIDE { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } + virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } + + void open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + virtual void close() CATCH_OVERRIDE { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NotStarted: + case CompletedSuccessfully: + case Failed: + throw std::logic_error( "Illogical state" ); + + case NeedsAnotherRun: + break;; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + default: + throw std::logic_error( "Unexpected state" ); + } + moveToParent(); + m_ctx.completeCycle(); + } + virtual void fail() CATCH_OVERRIDE { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { + m_runState = NeedsAnotherRun; + } + private: + void moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void moveToThis() { + m_ctx.setCurrentTracker( this ); + } + }; + + class SectionTracker : public TrackerBase { + std::vector m_filters; + public: + SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ) + { + if( parent ) { + while( !parent->isSectionTracker() ) + parent = &parent->parent(); + + SectionTracker& parentSection = static_cast( *parent ); + addNextFilters( parentSection.m_filters ); + } + } + virtual ~SectionTracker(); + + virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } + + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { + SectionTracker* section = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = static_cast( childTracker ); + } + else { + section = new SectionTracker( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() ) + section->tryOpen(); + return *section; + } + + void tryOpen() { + if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) + open(); + } + + void addInitialFilters( std::vector const& filters ) { + if( !filters.empty() ) { + m_filters.push_back(""); // Root - should never be consulted + m_filters.push_back(""); // Test Case - not a section filter + m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); + } + } + void addNextFilters( std::vector const& filters ) { + if( filters.size() > 1 ) + m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); + } + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index; + public: + IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( nameAndLocation, ctx, parent ), + m_size( size ), + m_index( -1 ) + {} + virtual ~IndexTracker(); + + virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } + + static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { + IndexTracker* tracker = CATCH_NULL; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITracker* childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isIndexTracker() ); + tracker = static_cast( childTracker ); + } + else { + tracker = new IndexTracker( nameAndLocation, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int index() const { return m_index; } + + void moveNext() { + m_index++; + m_children.clear(); + } + + virtual void close() CATCH_OVERRIDE { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + }; + + inline ITracker& TrackerContext::startRun() { + m_rootTracker = new SectionTracker( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, CATCH_NULL ); + m_currentTracker = CATCH_NULL; + m_runState = Executing; + return *m_rootTracker; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS + +// #included from: catch_fatal_condition.hpp +#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED + +namespace Catch { + + // Report the error condition + inline void reportFatal( std::string const& message ) { + IContext& context = Catch::getCurrentContext(); + IResultCapture* resultCapture = context.getResultCapture(); + resultCapture->handleFatalErrorCondition( message ); + } + +} // namespace Catch + +#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// +// #included from: catch_windows_h_proxy.h + +#define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED + +#ifdef CATCH_DEFINES_NOMINMAX +# define NOMINMAX +#endif +#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +#ifdef CATCH_DEFINES_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + + +# if !defined ( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + struct FatalConditionHandler { + void reset() {} + }; +} + +# else // CATCH_CONFIG_WINDOWS_SEH is defined + +namespace Catch { + + struct SignalDefs { DWORD id; const char* name; }; + extern SignalDefs signalDefs[]; + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + SignalDefs signalDefs[] = { + { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, + { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, + { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, + { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, + }; + + struct FatalConditionHandler { + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (int i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { + reportFatal(signalDefs[i].name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; + } + + FatalConditionHandler() { + isSet = true; + // 32k seems enough for Catch to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + exceptionHandlerHandle = CATCH_NULL; + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); + } + + static void reset() { + if (isSet) { + // Unregister handler and restore the old guarantee + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetThreadStackGuarantee(&guaranteeSize); + exceptionHandlerHandle = CATCH_NULL; + isSet = false; + } + } + + ~FatalConditionHandler() { + reset(); + } + private: + static bool isSet; + static ULONG guaranteeSize; + static PVOID exceptionHandlerHandle; + }; + + bool FatalConditionHandler::isSet = false; + ULONG FatalConditionHandler::guaranteeSize = 0; + PVOID FatalConditionHandler::exceptionHandlerHandle = CATCH_NULL; + +} // namespace Catch + +# endif // CATCH_CONFIG_WINDOWS_SEH + +#else // Not Windows - assumed to be POSIX compatible ////////////////////////// + +# if !defined(CATCH_CONFIG_POSIX_SIGNALS) + +namespace Catch { + struct FatalConditionHandler { + void reset() {} + }; +} + +# else // CATCH_CONFIG_POSIX_SIGNALS is defined + +#include + +namespace Catch { + + struct SignalDefs { + int id; + const char* name; + }; + extern SignalDefs signalDefs[]; + SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + + struct FatalConditionHandler { + + static bool isSet; + static struct sigaction oldSigActions [sizeof(signalDefs)/sizeof(SignalDefs)]; + static stack_t oldSigStack; + static char altStackMem[SIGSTKSZ]; + + static void handleSignal( int sig ) { + std::string name = ""; + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + SignalDefs &def = signalDefs[i]; + if (sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise( sig ); + } + + FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = SIGSTKSZ; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { 0 }; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + + ~FatalConditionHandler() { + reset(); + } + static void reset() { + if( isSet ) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { + sigaction(signalDefs[i].id, &oldSigActions[i], CATCH_NULL); + } + // Return the old stack + sigaltstack(&oldSigStack, CATCH_NULL); + isSet = false; + } + } + }; + + bool FatalConditionHandler::isSet = false; + struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; + +} // namespace Catch + +# endif // CATCH_CONFIG_POSIX_SIGNALS + +#endif // not Windows + +#include +#include +#include + +namespace Catch { + + class StreamRedirect { + + public: + StreamRedirect( std::ostream& stream, std::string& targetString ) + : m_stream( stream ), + m_prevBuf( stream.rdbuf() ), + m_targetString( targetString ) + { + stream.rdbuf( m_oss.rdbuf() ); + } + + ~StreamRedirect() { + m_targetString += m_oss.str(); + m_stream.rdbuf( m_prevBuf ); + } + + private: + std::ostream& m_stream; + std::streambuf* m_prevBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes and cannot use StreamRedirect on its own + class StdErrRedirect { + public: + StdErrRedirect(std::string& targetString) + :m_cerrBuf( cerr().rdbuf() ), m_clogBuf(clog().rdbuf()), + m_targetString(targetString){ + cerr().rdbuf(m_oss.rdbuf()); + clog().rdbuf(m_oss.rdbuf()); + } + ~StdErrRedirect() { + m_targetString += m_oss.str(); + cerr().rdbuf(m_cerrBuf); + clog().rdbuf(m_clogBuf); + } + private: + std::streambuf* m_cerrBuf; + std::streambuf* m_clogBuf; + std::ostringstream m_oss; + std::string& m_targetString; + }; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + RunContext( RunContext const& ); + void operator =( RunContext const& ); + + public: + + explicit RunContext( Ptr const& _config, Ptr const& reporter ) + : m_runInfo( _config->name() ), + m_context( getCurrentMutableContext() ), + m_activeTestCase( CATCH_NULL ), + m_config( _config ), + m_reporter( reporter ), + m_shouldReportUnexpected ( true ) + { + m_context.setRunner( this ); + m_context.setConfig( m_config ); + m_context.setResultCapture( this ); + m_reporter->testRunStarting( m_runInfo ); + } + + virtual ~RunContext() { + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); + } + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); + } + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { + m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); + } + + Totals runTest( TestCase const& testCase ) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + TestCaseInfo testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting( testInfo ); + + m_activeTestCase = &testCase; + + do { + ITracker& rootTracker = m_trackerContext.startRun(); + assert( rootTracker.isSectionTracker() ); + static_cast( rootTracker ).addInitialFilters( m_config->getSectionsToRun() ); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( testInfo.name, testInfo.lineInfo ) ); + runCurrentTest( redirectedCout, redirectedCerr ); + } + while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); + } + // !TBD: deprecated - this will be replaced by indexed trackers + while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); + + Totals deltaTotals = m_totals.delta( prevTotals ); + if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting() ) ); + + m_activeTestCase = CATCH_NULL; + m_testCaseTracker = CATCH_NULL; + + return deltaTotals; + } + + Ptr config() const { + return m_config; + } + + private: // IResultCapture + + virtual void assertionEnded( AssertionResult const& result ) { + if( result.getResultType() == ResultWas::Ok ) { + m_totals.assertions.passed++; + } + else if( !result.isOk() ) { + if( m_activeTestCase->getTestCaseInfo().okToFail() ) + m_totals.assertions.failedButOk++; + else + m_totals.assertions.failed++; + } + + // We have no use for the return value (whether messages should be cleared), because messages were made scoped + // and should be let to clear themselves out. + static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); + + // Reset working state + m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); + m_lastResult = result; + } + + virtual bool lastAssertionPassed() + { + return m_totals.assertions.passed == (m_prevPassed + 1); + } + + virtual void assertionPassed() + { + m_totals.assertions.passed++; + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"; + m_lastAssertionInfo.macroName = ""; + } + + virtual void assertionRun() + { + m_prevPassed = m_totals.assertions.passed; + } + + virtual bool sectionStarted ( + SectionInfo const& sectionInfo, + Counts& assertions + ) + { + ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, TestCaseTracking::NameAndLocation( sectionInfo.name, sectionInfo.lineInfo ) ); + if( !sectionTracker.isOpen() ) + return false; + m_activeSections.push_back( §ionTracker ); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting( sectionInfo ); + + assertions = m_totals.assertions; + + return true; + } + bool testForMissingAssertions( Counts& assertions ) { + if( assertions.total() != 0 ) + return false; + if( !m_config->warnAboutMissingAssertions() ) + return false; + if( m_trackerContext.currentTracker().hasChildren() ) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + virtual void sectionEnded( SectionEndInfo const& endInfo ) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + if( !m_activeSections.empty() ) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); + m_messages.clear(); + } + + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { + if( m_unfinishedSections.empty() ) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back( endInfo ); + } + + virtual void pushScopedMessage( MessageInfo const& message ) { + m_messages.push_back( message ); + } + + virtual void popScopedMessage( MessageInfo const& message ) { + m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); + } + + virtual std::string getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : std::string(); + } + + virtual const AssertionResult* getLastResult() const { + return &m_lastResult; + } + + virtual void exceptionEarlyReported() { + m_shouldReportUnexpected = false; + } + + virtual void handleFatalErrorCondition( std::string const& message ) { + // Don't rebuild the result -- the stringification itself can cause more fatal errors + // Instead, fake a result data. + AssertionResultData tempResult; + tempResult.resultType = ResultWas::FatalErrorCondition; + tempResult.message = message; + AssertionResult result(m_lastAssertionInfo, tempResult); + + getResultCapture().assertionEnded(result); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); + m_reporter->sectionEnded( testCaseSectionStats ); + + TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + deltaTotals.assertions.failed = 1; + m_reporter->testCaseEnded( TestCaseStats( testInfo, + deltaTotals, + std::string(), + std::string(), + false ) ); + m_totals.testCases.failed++; + testGroupEnded( std::string(), m_totals, 1, 1 ); + m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); + } + + public: + // !TBD We need to do this another way! + bool aborting() const { + return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); + } + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { + TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); + m_reporter->sectionStarting( testCaseSection ); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + m_shouldReportUnexpected = true; + try { + m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); + + seedRng( *m_config ); + + Timer timer; + timer.start(); + if( m_reporter->getPreferences().shouldRedirectStdOut ) { + StreamRedirect coutRedir( Catch::cout(), redirectedCout ); + StdErrRedirect errRedir( redirectedCerr ); + invokeActiveTestCase(); + } + else { + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } + catch( TestFailureException& ) { + // This just means the test was aborted due to failure + } + catch(...) { + // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions + // are reported without translation at the point of origin. + if (m_shouldReportUnexpected) { + makeUnexpectedResultBuilder().useActiveException(); + } + } + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions( assertions ); + + SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); + m_reporter->sectionEnded( testCaseSectionStats ); + } + + void invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); + } + + private: + + ResultBuilder makeUnexpectedResultBuilder() const { + return ResultBuilder( m_lastAssertionInfo.macroName, + m_lastAssertionInfo.lineInfo, + m_lastAssertionInfo.capturedExpression, + m_lastAssertionInfo.resultDisposition ); + } + + void handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it ) + sectionEnded( *it ); + m_unfinishedSections.clear(); + } + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase; + ITracker* m_testCaseTracker; + ITracker* m_currentSectionTracker; + AssertionResult m_lastResult; + + Ptr m_config; + Totals m_totals; + Ptr m_reporter; + std::vector m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; + size_t m_prevPassed; + bool m_shouldReportUnexpected; + }; + + IResultCapture& getResultCapture() { + if( IResultCapture* capture = getCurrentContext().getResultCapture() ) + return *capture; + else + throw std::logic_error( "No result capture instance" ); + } + +} // end namespace Catch + +// #included from: internal/catch_version.h +#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED + +namespace Catch { + + // Versioning information + struct Version { + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + char const * const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + + private: + void operator=( Version const& ); + }; + + inline Version libraryVersion(); +} + +#include +#include +#include + +namespace Catch { + + Ptr createReporter( std::string const& reporterName, Ptr const& config ) { + Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); + if( !reporter ) { + std::ostringstream oss; + oss << "No reporter registered with name: '" << reporterName << "'"; + throw std::domain_error( oss.str() ); + } + return reporter; + } + +#if !defined(CATCH_CONFIG_DEFAULT_REPORTER) +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + + Ptr makeReporter( Ptr const& config ) { + std::vector reporters = config->getReporterNames(); + if( reporters.empty() ) + reporters.push_back( CATCH_CONFIG_DEFAULT_REPORTER ); + + Ptr reporter; + for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); + it != itEnd; + ++it ) + reporter = addReporter( reporter, createReporter( *it, config ) ); + return reporter; + } + Ptr addListeners( Ptr const& config, Ptr reporters ) { + IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); + for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); + it != itEnd; + ++it ) + reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); + return reporters; + } + + Totals runTests( Ptr const& config ) { + + Ptr iconfig = config.get(); + + Ptr reporter = makeReporter( config ); + reporter = addListeners( iconfig, reporter ); + + RunContext context( iconfig, reporter ); + + Totals totals; + + context.testGroupStarting( config->name(), 1, 1 ); + + TestSpec testSpec = config->testSpec(); + if( !testSpec.hasFilters() ) + testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests + + std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); + for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); + it != itEnd; + ++it ) { + if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) + totals += context.runTest( *it ); + else + reporter->skipTest( *it ); + } + + context.testGroupEnded( iconfig->name(), totals, 1, 1 ); + return totals; + } + + void applyFilenamesAsTags( IConfig const& config ) { + std::vector const& tests = getAllTestCasesSorted( config ); + for(std::size_t i = 0; i < tests.size(); ++i ) { + TestCase& test = const_cast( tests[i] ); + std::set tags = test.tags; + + std::string filename = test.lineInfo.file; + std::string::size_type lastSlash = filename.find_last_of( "\\/" ); + if( lastSlash != std::string::npos ) + filename = filename.substr( lastSlash+1 ); + + std::string::size_type lastDot = filename.find_last_of( '.' ); + if( lastDot != std::string::npos ) + filename = filename.substr( 0, lastDot ); + + tags.insert( '#' + filename ); + setTags( test, tags ); + } + } + + class Session : NonCopyable { + static bool alreadyInstantiated; + + public: + + struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; + + Session() + : m_cli( makeCommandLineParser() ) { + if( alreadyInstantiated ) { + std::string msg = "Only one instance of Catch::Session can ever be used"; + Catch::cerr() << msg << std::endl; + throw std::logic_error( msg ); + } + alreadyInstantiated = true; + } + ~Session() { + Catch::cleanUp(); + } + + void showHelp( std::string const& processName ) { + Catch::cout() << "\nCatch v" << libraryVersion() << "\n"; + + m_cli.usage( Catch::cout(), processName ); + Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; + } + void libIdentify() { + Catch::cout() + << std::left << std::setw(16) << "description: " << "A Catch test executable\n" + << std::left << std::setw(16) << "category: " << "testframework\n" + << std::left << std::setw(16) << "framework: " << "Catch Test\n" + << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; + } + + int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { + try { + m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); + m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); + if( m_configData.showHelp ) + showHelp( m_configData.processName ); + if( m_configData.libIdentify ) + libIdentify(); + m_config.reset(); + } + catch( std::exception& ex ) { + { + Colour colourGuard( Colour::Red ); + Catch::cerr() + << "\nError(s) in input:\n" + << Text( ex.what(), TextAttributes().setIndent(2) ) + << "\n\n"; + } + m_cli.usage( Catch::cout(), m_configData.processName ); + return (std::numeric_limits::max)(); + } + return 0; + } + + void useConfigData( ConfigData const& _configData ) { + m_configData = _configData; + m_config.reset(); + } + + int run( int argc, char const* const* const argv ) { + + int returnCode = applyCommandLine( argc, argv ); + if( returnCode == 0 ) + returnCode = run(); + return returnCode; + } + + #if defined(WIN32) && defined(UNICODE) + int run( int argc, wchar_t const* const* const argv ) { + + char **utf8Argv = new char *[ argc ]; + + for ( int i = 0; i < argc; ++i ) { + int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); + + utf8Argv[ i ] = new char[ bufSize ]; + + WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); + } + + int returnCode = applyCommandLine( argc, utf8Argv ); + if( returnCode == 0 ) + returnCode = run(); + + for ( int i = 0; i < argc; ++i ) + delete [] utf8Argv[ i ]; + + delete [] utf8Argv; + + return returnCode; + } + #endif + + int run() { + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before starting" << std::endl; + static_cast(std::getchar()); + } + int exitCode = runInternal(); + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; + static_cast(std::getchar()); + } + return exitCode; + } + + Clara::CommandLine const& cli() const { + return m_cli; + } + std::vector const& unusedTokens() const { + return m_unusedTokens; + } + ConfigData& configData() { + return m_configData; + } + Config& config() { + if( !m_config ) + m_config = new Config( m_configData ); + return *m_config; + } + private: + + int runInternal() { + if( m_configData.showHelp || m_configData.libIdentify ) + return 0; + + try + { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option listed = list( config() ) ) + return static_cast( *listed ); + + return static_cast( runTests( m_config ).assertions.failed ); + } + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return (std::numeric_limits::max)(); + } + } + + Clara::CommandLine m_cli; + std::vector m_unusedTokens; + ConfigData m_configData; + Ptr m_config; + }; + + bool Session::alreadyInstantiated = false; + +} // end namespace Catch + +// #included from: catch_registry_hub.hpp +#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED + +// #included from: catch_test_case_registry_impl.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + struct RandomNumberGenerator { + typedef unsigned int result_type; + + result_type operator()( result_type n ) const { return std::rand() % n; } + +#ifdef CATCH_CONFIG_CPP11_SHUFFLE + static constexpr result_type (min)() { return 0; } + static constexpr result_type (max)() { return 1000000; } + result_type operator()() const { return std::rand() % (max)(); } +#endif + template + static void shuffle( V& vector ) { + RandomNumberGenerator rng; +#ifdef CATCH_CONFIG_CPP11_SHUFFLE + std::shuffle( vector.begin(), vector.end(), rng ); +#else + std::random_shuffle( vector.begin(), vector.end(), rng ); +#endif + } + }; + + inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { + + std::vector sorted = unsortedTestCases; + + switch( config.runOrder() ) { + case RunTests::InLexicographicalOrder: + std::sort( sorted.begin(), sorted.end() ); + break; + case RunTests::InRandomOrder: + { + seedRng( config ); + RandomNumberGenerator::shuffle( sorted ); + } + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; + } + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); + } + + void enforceNoDuplicateTestCases( std::vector const& functions ) { + std::set seenFunctions; + for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); + it != itEnd; + ++it ) { + std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); + if( !prev.second ) { + std::ostringstream ss; + + ss << Colour( Colour::Red ) + << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << '\n' + << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; + + throw std::runtime_error(ss.str()); + } + } + } + + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector filtered; + filtered.reserve( testCases.size() ); + for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); + it != itEnd; + ++it ) + if( matchTest( *it, testSpec, config ) ) + filtered.push_back( *it ); + return filtered; + } + std::vector const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + class TestRegistry : public ITestCaseRegistry { + public: + TestRegistry() + : m_currentSortOrder( RunTests::InDeclarationOrder ), + m_unnamedCount( 0 ) + {} + virtual ~TestRegistry(); + + virtual void registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name.empty() ) { + std::ostringstream oss; + oss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( oss.str() ) ); + } + m_functions.push_back( testCase ); + } + + virtual std::vector const& getAllTests() const { + return m_functions; + } + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + private: + std::vector m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder; + mutable std::vector m_sortedFunctions; + size_t m_unnamedCount; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class FreeFunctionTestCase : public SharedImpl { + public: + + FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} + + virtual void invoke() const { + m_fun(); + } + + private: + virtual ~FreeFunctionTestCase(); + + TestFunction m_fun; + }; + + inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { + std::string className = classOrQualifiedMethodName; + if( startsWith( className, '&' ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + + void registerTestCase + ( ITestCase* testCase, + char const* classOrQualifiedMethodName, + NameAndDesc const& nameAndDesc, + SourceLineInfo const& lineInfo ) { + + getMutableRegistryHub().registerTest + ( makeTestCase + ( testCase, + extractClassName( classOrQualifiedMethodName ), + nameAndDesc.name, + nameAndDesc.description, + lineInfo ) ); + } + void registerTestCaseFunction + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); + } + + /////////////////////////////////////////////////////////////////////////// + + AutoReg::AutoReg + ( TestFunction function, + SourceLineInfo const& lineInfo, + NameAndDesc const& nameAndDesc ) { + registerTestCaseFunction( function, lineInfo, nameAndDesc ); + } + + AutoReg::~AutoReg() {} + +} // end namespace Catch + +// #included from: catch_reporter_registry.hpp +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED + +#include + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + virtual ~ReporterRegistry() CATCH_OVERRIDE {} + + virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { + FactoryMap::const_iterator it = m_factories.find( name ); + if( it == m_factories.end() ) + return CATCH_NULL; + return it->second->create( ReporterConfig( config ) ); + } + + void registerReporter( std::string const& name, Ptr const& factory ) { + m_factories.insert( std::make_pair( name, factory ) ); + } + void registerListener( Ptr const& factory ) { + m_listeners.push_back( factory ); + } + + virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { + return m_factories; + } + virtual Listeners const& getListeners() const CATCH_OVERRIDE { + return m_listeners; + } + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +// #included from: catch_exception_translator_registry.hpp +#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED + +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry() { + deleteAll( m_translators ); + } + + virtual void registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( translator ); + } + + virtual std::string translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::toString( [exception description] ); + } +#else + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + throw; + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string tryTranslators() const { + if( m_translators.empty() ) + throw; + else + return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); + } + + private: + std::vector m_translators; + }; +} + +// #included from: catch_tag_alias_registry.h +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED + +#include + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + virtual ~TagAliasRegistry(); + virtual Option find( std::string const& alias ) const; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; + void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); + + private: + std::map m_registry; + }; + +} // end namespace Catch + +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub { + + RegistryHub( RegistryHub const& ); + void operator=( RegistryHub const& ); + + public: // IRegistryHub + RegistryHub() { + } + virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { + return m_reporterRegistry; + } + virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { + return m_testCaseRegistry; + } + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { + return m_exceptionTranslatorRegistry; + } + virtual ITagAliasRegistry const& getTagAliasRegistry() const CATCH_OVERRIDE { + return m_tagAliasRegistry; + } + + public: // IMutableRegistryHub + virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerReporter( name, factory ); + } + virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { + m_reporterRegistry.registerListener( factory ); + } + virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { + m_testCaseRegistry.registerTest( testInfo ); + } + virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) CATCH_OVERRIDE { + m_tagAliasRegistry.add( alias, tag, lineInfo ); + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + TagAliasRegistry m_tagAliasRegistry; + }; + + // Single, global, instance + inline RegistryHub*& getTheRegistryHub() { + static RegistryHub* theRegistryHub = CATCH_NULL; + if( !theRegistryHub ) + theRegistryHub = new RegistryHub(); + return theRegistryHub; + } + } + + IRegistryHub& getRegistryHub() { + return *getTheRegistryHub(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return *getTheRegistryHub(); + } + void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = CATCH_NULL; + cleanUpContext(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + +} // end namespace Catch + +// #included from: catch_notimplemented_exception.hpp +#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED + +#include + +namespace Catch { + + NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) + : m_lineInfo( lineInfo ) { + std::ostringstream oss; + oss << lineInfo << ": function "; + oss << "not implemented"; + m_what = oss.str(); + } + + const char* NotImplementedException::what() const CATCH_NOEXCEPT { + return m_what.c_str(); + } + +} // end namespace Catch + +// #included from: catch_context_impl.hpp +#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED + +// #included from: catch_stream.hpp +#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + template + class StreamBufImpl : public StreamBufBase { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() CATCH_NOEXCEPT { + sync(); + } + + private: + int overflow( int c ) { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast( c ) ) ); + else + sputc( static_cast( c ) ); + } + return 0; + } + + int sync() { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + FileStream::FileStream( std::string const& filename ) { + m_ofs.open( filename.c_str() ); + if( m_ofs.fail() ) { + std::ostringstream oss; + oss << "Unable to open file: '" << filename << '\''; + throw std::domain_error( oss.str() ); + } + } + + std::ostream& FileStream::stream() const { + return m_ofs; + } + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + DebugOutStream::DebugOutStream() + : m_streamBuf( new StreamBufImpl() ), + m_os( m_streamBuf.get() ) + {} + + std::ostream& DebugOutStream::stream() const { + return m_os; + } + + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream::CoutStream() + : m_os( Catch::cout().rdbuf() ) + {} + + std::ostream& CoutStream::stream() const { + return m_os; + } + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { + return std::cout; + } + std::ostream& cerr() { + return std::cerr; + } + std::ostream& clog() { + return std::clog; + } +#endif +} + +namespace Catch { + + class Context : public IMutableContext { + + Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} + Context( Context const& ); + void operator=( Context const& ); + + public: + virtual ~Context() { + deleteAllValues( m_generatorsByTestName ); + } + + public: // IContext + virtual IResultCapture* getResultCapture() { + return m_resultCapture; + } + virtual IRunner* getRunner() { + return m_runner; + } + virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { + return getGeneratorsForCurrentTest() + .getGeneratorInfo( fileInfo, totalSize ) + .getCurrentIndex(); + } + virtual bool advanceGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + return generators && generators->moveNext(); + } + + virtual Ptr getConfig() const { + return m_config; + } + + public: // IMutableContext + virtual void setResultCapture( IResultCapture* resultCapture ) { + m_resultCapture = resultCapture; + } + virtual void setRunner( IRunner* runner ) { + m_runner = runner; + } + virtual void setConfig( Ptr const& config ) { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IGeneratorsForTest* findGeneratorsForCurrentTest() { + std::string testName = getResultCapture()->getCurrentTestName(); + + std::map::const_iterator it = + m_generatorsByTestName.find( testName ); + return it != m_generatorsByTestName.end() + ? it->second + : CATCH_NULL; + } + + IGeneratorsForTest& getGeneratorsForCurrentTest() { + IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); + if( !generators ) { + std::string testName = getResultCapture()->getCurrentTestName(); + generators = createGeneratorsForTest(); + m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); + } + return *generators; + } + + private: + Ptr m_config; + IRunner* m_runner; + IResultCapture* m_resultCapture; + std::map m_generatorsByTestName; + }; + + namespace { + Context* currentContext = CATCH_NULL; + } + IMutableContext& getCurrentMutableContext() { + if( !currentContext ) + currentContext = new Context(); + return *currentContext; + } + IContext& getCurrentContext() { + return getCurrentMutableContext(); + } + + void cleanUpContext() { + delete currentContext; + currentContext = CATCH_NULL; + } +} + +// #included from: catch_console_colour_impl.hpp +#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED + +// #included from: catch_errno_guard.hpp +#define TWOBLUECUBES_CATCH_ERRNO_GUARD_HPP_INCLUDED + +#include + +namespace Catch { + + class ErrnoGuard { + public: + ErrnoGuard():m_oldErrno(errno){} + ~ErrnoGuard() { errno = m_oldErrno; } + private: + int m_oldErrno; + }; + +} + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() {} + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = !isDebuggerActive() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + virtual void use( Colour::Code _colourCode ) { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0;34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + + case Colour::Bright: throw std::logic_error( "not a colour" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + Catch::cout() << '\033' << _escapeCode; + } + }; + + IColourImpl* platformColourInstance() { + ErrnoGuard guard; + Ptr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } + Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + impl->use( _colourCode ); + } + +} // end namespace Catch + +// #included from: catch_generators_impl.hpp +#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct GeneratorInfo : IGeneratorInfo { + + GeneratorInfo( std::size_t size ) + : m_size( size ), + m_currentIndex( 0 ) + {} + + bool moveNext() { + if( ++m_currentIndex == m_size ) { + m_currentIndex = 0; + return false; + } + return true; + } + + std::size_t getCurrentIndex() const { + return m_currentIndex; + } + + std::size_t m_size; + std::size_t m_currentIndex; + }; + + /////////////////////////////////////////////////////////////////////////// + + class GeneratorsForTest : public IGeneratorsForTest { + + public: + ~GeneratorsForTest() { + deleteAll( m_generatorsInOrder ); + } + + IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { + std::map::const_iterator it = m_generatorsByName.find( fileInfo ); + if( it == m_generatorsByName.end() ) { + IGeneratorInfo* info = new GeneratorInfo( size ); + m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); + m_generatorsInOrder.push_back( info ); + return *info; + } + return *it->second; + } + + bool moveNext() { + std::vector::const_iterator it = m_generatorsInOrder.begin(); + std::vector::const_iterator itEnd = m_generatorsInOrder.end(); + for(; it != itEnd; ++it ) { + if( (*it)->moveNext() ) + return true; + } + return false; + } + + private: + std::map m_generatorsByName; + std::vector m_generatorsInOrder; + }; + + IGeneratorsForTest* createGeneratorsForTest() + { + return new GeneratorsForTest(); + } + +} // end namespace Catch + +// #included from: catch_assertionresult.hpp +#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED + +namespace Catch { + + AssertionInfo::AssertionInfo():macroName(""), capturedExpression(""), resultDisposition(ResultDisposition::Normal), secondArg(""){} + + AssertionInfo::AssertionInfo( char const * _macroName, + SourceLineInfo const& _lineInfo, + char const * _capturedExpression, + ResultDisposition::Flags _resultDisposition, + char const * _secondArg) + : macroName( _macroName ), + lineInfo( _lineInfo ), + capturedExpression( _capturedExpression ), + resultDisposition( _resultDisposition ), + secondArg( _secondArg ) + {} + + AssertionResult::AssertionResult() {} + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + AssertionResult::~AssertionResult() {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return m_info.capturedExpression[0] != 0; + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string capturedExpressionWithSecondArgument( char const * capturedExpression, char const * secondArg ) { + return (secondArg[0] == 0 || secondArg[0] == '"' && secondArg[1] == '"') + ? capturedExpression + : std::string(capturedExpression) + ", " + secondArg; + } + + std::string AssertionResult::getExpression() const { + if( isFalseTest( m_info.resultDisposition ) ) + return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")"; + else + return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); + } + std::string AssertionResult::getExpressionInMacro() const { + if( m_info.macroName[0] == 0 ) + return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg); + else + return std::string(m_info.macroName) + "( " + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + " )"; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + return m_resultData.reconstructExpression(); + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + std::string AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + + void AssertionResult::discardDecomposedExpression() const { + m_resultData.decomposedExpression = CATCH_NULL; + } + + void AssertionResult::expandDecomposedExpression() const { + m_resultData.reconstructExpression(); + } + +} // end namespace Catch + +// #included from: catch_test_case_info.hpp +#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED + +#include + +namespace Catch { + + inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "hide" || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else + return TestCaseInfo::None; + } + inline bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); + } + inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + if( isReservedTag( tag ) ) { + std::ostringstream ss; + ss << Colour(Colour::Red) + << "Tag name [" << tag << "] not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n" + << Colour(Colour::FileName) + << _lineInfo << '\n'; + throw std::runtime_error(ss.str()); + } + } + + TestCase makeTestCase( ITestCase* _testCase, + std::string const& _className, + std::string const& _name, + std::string const& _descOrTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden( startsWith( _name, "./" ) ); // Legacy support + + // Parse out tags + std::set tags; + std::string desc, tag; + bool inTag = false; + for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { + char c = _descOrTags[i]; + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( prop == TestCaseInfo::IsHidden ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + tags.insert( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + tags.insert( "hide" ); + tags.insert( "." ); + } + + TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, info ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) + { + testCaseInfo.tags = tags; + testCaseInfo.lcaseTags.clear(); + + std::ostringstream oss; + for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { + oss << '[' << *it << ']'; + std::string lcaseTag = toLower( *it ); + testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.insert( lcaseTag ); + } + testCaseInfo.tagsAsString = oss.str(); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::set const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) + : name( other.name ), + className( other.className ), + description( other.description ), + tags( other.tags ), + lcaseTags( other.lcaseTags ), + tagsAsString( other.tagsAsString ), + lineInfo( other.lineInfo ), + properties( other.properties ) + {} + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} + + TestCase::TestCase( TestCase const& other ) + : TestCaseInfo( other ), + test( other.test ) + {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::swap( TestCase& other ) { + test.swap( other.test ); + name.swap( other.name ); + className.swap( other.className ); + description.swap( other.description ); + tags.swap( other.tags ); + lcaseTags.swap( other.lcaseTags ); + tagsAsString.swap( other.tagsAsString ); + std::swap( TestCaseInfo::properties, static_cast( other ).properties ); + std::swap( lineInfo, other.lineInfo ); + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + TestCase& TestCase::operator = ( TestCase const& other ) { + TestCase temp( other ); + swap( temp ); + return *this; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch + +// #included from: catch_version.hpp +#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << '.' + << version.minorVersion << '.' + << version.patchNumber; + // branchName is never null -> 0th char is \0 if it is empty + if (version.branchName[0]) { + os << '-' << version.branchName + << '.' << version.buildNumber; + } + return os; + } + + inline Version libraryVersion() { + static Version version( 1, 12, 2, "", 0 ); + return version; + } + +} + +// #included from: catch_message.hpp +#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED + +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ) + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + ScopedMessage::ScopedMessage( ScopedMessage const& other ) + : m_info( other.m_info ) + {} + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 +#endif + ScopedMessage::~ScopedMessage() { + if ( !std::uncaught_exception() ){ + getResultCapture().popScopedMessage(m_info); + } + } +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +} // end namespace Catch + +// #included from: catch_legacy_reporter_adapter.hpp +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED + +// #included from: catch_legacy_reporter_adapter.h +#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED + +namespace Catch +{ + // Deprecated + struct IReporter : IShared { + virtual ~IReporter(); + + virtual bool shouldRedirectStdout() const = 0; + + virtual void StartTesting() = 0; + virtual void EndTesting( Totals const& totals ) = 0; + virtual void StartGroup( std::string const& groupName ) = 0; + virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; + virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; + virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; + virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; + virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; + virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; + virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; + virtual void Aborted() = 0; + virtual void Result( AssertionResult const& result ) = 0; + }; + + class LegacyReporterAdapter : public SharedImpl + { + public: + LegacyReporterAdapter( Ptr const& legacyReporter ); + virtual ~LegacyReporterAdapter(); + + virtual ReporterPreferences getPreferences() const; + virtual void noMatchingTestCases( std::string const& ); + virtual void testRunStarting( TestRunInfo const& ); + virtual void testGroupStarting( GroupInfo const& groupInfo ); + virtual void testCaseStarting( TestCaseInfo const& testInfo ); + virtual void sectionStarting( SectionInfo const& sectionInfo ); + virtual void assertionStarting( AssertionInfo const& ); + virtual bool assertionEnded( AssertionStats const& assertionStats ); + virtual void sectionEnded( SectionStats const& sectionStats ); + virtual void testCaseEnded( TestCaseStats const& testCaseStats ); + virtual void testGroupEnded( TestGroupStats const& testGroupStats ); + virtual void testRunEnded( TestRunStats const& testRunStats ); + virtual void skipTest( TestCaseInfo const& ); + + private: + Ptr m_legacyReporter; + }; +} + +namespace Catch +{ + LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) + : m_legacyReporter( legacyReporter ) + {} + LegacyReporterAdapter::~LegacyReporterAdapter() {} + + ReporterPreferences LegacyReporterAdapter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); + return prefs; + } + + void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} + void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { + m_legacyReporter->StartTesting(); + } + void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { + m_legacyReporter->StartGroup( groupInfo.name ); + } + void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { + m_legacyReporter->StartTestCase( testInfo ); + } + void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { + m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); + } + void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { + // Not on legacy interface + } + + bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info ) { + ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); + rb << it->message; + rb.setResultType( ResultWas::Info ); + AssertionResult result = rb.build(); + m_legacyReporter->Result( result ); + } + } + } + m_legacyReporter->Result( assertionStats.assertionResult ); + return true; + } + void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { + if( sectionStats.missingAssertions ) + m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); + m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); + } + void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { + m_legacyReporter->EndTestCase + ( testCaseStats.testInfo, + testCaseStats.totals, + testCaseStats.stdOut, + testCaseStats.stdErr ); + } + void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { + if( testGroupStats.aborting ) + m_legacyReporter->Aborted(); + m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); + } + void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { + m_legacyReporter->EndTesting( testRunStats.totals ); + } + void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { + } +} + +// #included from: catch_timer.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++11-long-long" +#endif + +#ifdef CATCH_PLATFORM_WINDOWS + +#else + +#include + +#endif + +namespace Catch { + + namespace { +#ifdef CATCH_PLATFORM_WINDOWS + UInt64 getCurrentTicks() { + static UInt64 hz=0, hzo=0; + if (!hz) { + QueryPerformanceFrequency( reinterpret_cast( &hz ) ); + QueryPerformanceCounter( reinterpret_cast( &hzo ) ); + } + UInt64 t; + QueryPerformanceCounter( reinterpret_cast( &t ) ); + return ((t-hzo)*1000000)/hz; + } +#else + UInt64 getCurrentTicks() { + timeval t; + gettimeofday(&t,CATCH_NULL); + return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); + } +#endif + } + + void Timer::start() { + m_ticks = getCurrentTicks(); + } + unsigned int Timer::getElapsedMicroseconds() const { + return static_cast(getCurrentTicks() - m_ticks); + } + unsigned int Timer::getElapsedMilliseconds() const { + return static_cast(getElapsedMicroseconds()/1000); + } + double Timer::getElapsedSeconds() const { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +// #included from: catch_common.hpp +#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED + +#include +#include + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s[0] == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s[s.size()-1] == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + char toLowerCh(char c) { + return static_cast( std::tolower( c ) ); + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << 's'; + return os; + } + + SourceLineInfo::SourceLineInfo() : file(""), line( 0 ){} + SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) + : file( _file ), + line( _line ) + {} + bool SourceLineInfo::empty() const { + return file[0] == '\0'; + } + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { + return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); + } + + void seedRng( IConfig const& config ) { + if( config.rngSeed() != 0 ) + std::srand( config.rngSeed() ); + } + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; + } + + void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { + std::ostringstream oss; + oss << locationInfo << ": Internal Catch error: '" << message << '\''; + if( alwaysTrue() ) + throw std::logic_error( oss.str() ); + } +} + +// #included from: catch_section.hpp +#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description ) + : name( _name ), + description( _description ), + lineInfo( _lineInfo ) + {} + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17 +#endif + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); + if( std::uncaught_exception() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + +} // end namespace Catch + +// #included from: catch_debugger.hpp +#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED + +#ifdef CATCH_PLATFORM_MAC + + #include + #include + #include + #include + #include + + namespace Catch{ + + // The following function is taken directly from the following technical note: + // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + } // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) + #include + #include + + namespace Catch{ + // The standard POSIX way of detecting a debugger is to attempt to + // ptrace() the process, but this needs to be done from a child and not + // this process itself to still allow attaching to this process later + // if wanted, so is rather heavy. Under Linux we have the PID of the + // "debugger" (which doesn't need to be gdb, of course, it could also + // be strace, for example) in /proc/$PID/status, so just get it from + // there instead. + bool isDebuggerActive(){ + // Libstdc++ has a bug, where std::ifstream sets errno to 0 + // This way our users can properly assert over errno values + ErrnoGuard guard; + std::ifstream in("/proc/self/status"); + for( std::string line; std::getline(in, line); ) { + static const int PREFIX_LEN = 11; + if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; + } + } // namespace Catch +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + inline bool isDebuggerActive() { return false; } + } +#endif // Platform + +#ifdef CATCH_PLATFORM_WINDOWS + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } +#else + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } +#endif // Platform + +// #included from: catch_tostring.hpp +#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _{ + int asInt; + char asChar[sizeof (int)]; + } u; + + u.asInt = 1; + return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) + { + // Reverse order for little endian architectures + int i = 0, end = static_cast( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast(object); + std::ostringstream os; + os << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + os << std::setw(2) << static_cast(bytes[i]); + return os.str(); + } +} + +std::string toString( std::string const& value ) { + std::string s = value; + if( getCurrentContext().getConfig()->showInvisibles() ) { + for(size_t i = 0; i < s.size(); ++i ) { + std::string subs; + switch( s[i] ) { + case '\n': subs = "\\n"; break; + case '\t': subs = "\\t"; break; + default: break; + } + if( !subs.empty() ) { + s = s.substr( 0, i ) + subs + s.substr( i+1 ); + ++i; + } + } + } + return '"' + s + '"'; +} +std::string toString( std::wstring const& value ) { + + std::string s; + s.reserve( value.size() ); + for(size_t i = 0; i < value.size(); ++i ) + s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; + return Catch::toString( s ); +} + +std::string toString( const char* const value ) { + return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); +} + +std::string toString( char* const value ) { + return Catch::toString( static_cast( value ) ); +} + +std::string toString( const wchar_t* const value ) +{ + return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); +} + +std::string toString( wchar_t* const value ) +{ + return Catch::toString( static_cast( value ) ); +} + +std::string toString( int value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} + +std::string toString( unsigned long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} + +std::string toString( unsigned int value ) { + return Catch::toString( static_cast( value ) ); +} + +template +std::string fpToString( T value, int precision ) { + std::ostringstream oss; + oss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = oss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +std::string toString( const double value ) { + return fpToString( value, 10 ); +} +std::string toString( const float value ) { + return fpToString( value, 5 ) + 'f'; +} + +std::string toString( bool value ) { + return value ? "true" : "false"; +} + +std::string toString( char value ) { + if ( value == '\r' ) + return "'\\r'"; + if ( value == '\f' ) + return "'\\f'"; + if ( value == '\n' ) + return "'\\n'"; + if ( value == '\t' ) + return "'\\t'"; + if ( '\0' <= value && value < ' ' ) + return toString( static_cast( value ) ); + char chstr[] = "' '"; + chstr[1] = value; + return chstr; +} + +std::string toString( signed char value ) { + return toString( static_cast( value ) ); +} + +std::string toString( unsigned char value ) { + return toString( static_cast( value ) ); +} + +#ifdef CATCH_CONFIG_CPP11_LONG_LONG +std::string toString( long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} +std::string toString( unsigned long long value ) { + std::ostringstream oss; + oss << value; + if( value > Detail::hexThreshold ) + oss << " (0x" << std::hex << value << ')'; + return oss.str(); +} +#endif + +#ifdef CATCH_CONFIG_CPP11_NULLPTR +std::string toString( std::nullptr_t ) { + return "nullptr"; +} +#endif + +#ifdef __OBJC__ + std::string toString( NSString const * const& nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSString * CATCH_ARC_STRONG & nsstring ) { + if( !nsstring ) + return "nil"; + return "@" + toString([nsstring UTF8String]); + } + std::string toString( NSObject* const& nsObject ) { + return toString( [nsObject description] ); + } +#endif + +} // end namespace Catch + +// #included from: catch_result_builder.hpp +#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED + +#include + +namespace Catch { + + ResultBuilder::ResultBuilder( char const* macroName, + SourceLineInfo const& lineInfo, + char const* capturedExpression, + ResultDisposition::Flags resultDisposition, + char const* secondArg ) + : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition, secondArg ), + m_shouldDebugBreak( false ), + m_shouldThrow( false ), + m_guardException( false ), + m_usedStream( false ) + {} + + ResultBuilder::~ResultBuilder() { +#if defined(CATCH_CONFIG_FAST_COMPILE) + if ( m_guardException ) { + stream().oss << "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + captureResult( ResultWas::ThrewException ); + getCurrentContext().getResultCapture()->exceptionEarlyReported(); + } +#endif + } + + ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { + m_data.resultType = result; + return *this; + } + ResultBuilder& ResultBuilder::setResultType( bool result ) { + m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; + return *this; + } + + void ResultBuilder::endExpression( DecomposedExpression const& expr ) { + // Flip bool results if FalseTest flag is set + if( isFalseTest( m_assertionInfo.resultDisposition ) ) { + m_data.negate( expr.isBinaryExpression() ); + } + + getResultCapture().assertionRun(); + + if(getCurrentContext().getConfig()->includeSuccessfulResults() || m_data.resultType != ResultWas::Ok) + { + AssertionResult result = build( expr ); + handleResult( result ); + } + else + getResultCapture().assertionPassed(); + } + + void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { + m_assertionInfo.resultDisposition = resultDisposition; + stream().oss << Catch::translateActiveException(); + captureResult( ResultWas::ThrewException ); + } + + void ResultBuilder::captureResult( ResultWas::OfType resultType ) { + setResultType( resultType ); + captureExpression(); + } + + void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { + if( expectedMessage.empty() ) + captureExpectedException( Matchers::Impl::MatchAllOf() ); + else + captureExpectedException( Matchers::Equals( expectedMessage ) ); + } + + void ResultBuilder::captureExpectedException( Matchers::Impl::MatcherBase const& matcher ) { + + assert( !isFalseTest( m_assertionInfo.resultDisposition ) ); + AssertionResultData data = m_data; + data.resultType = ResultWas::Ok; + data.reconstructedExpression = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); + + std::string actualMessage = Catch::translateActiveException(); + if( !matcher.match( actualMessage ) ) { + data.resultType = ResultWas::ExpressionFailed; + data.reconstructedExpression = actualMessage; + } + AssertionResult result( m_assertionInfo, data ); + handleResult( result ); + } + + void ResultBuilder::captureExpression() { + AssertionResult result = build(); + handleResult( result ); + } + + void ResultBuilder::handleResult( AssertionResult const& result ) + { + getResultCapture().assertionEnded( result ); + + if( !result.isOk() ) { + if( getCurrentContext().getConfig()->shouldDebugBreak() ) + m_shouldDebugBreak = true; + if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) + m_shouldThrow = true; + } + } + + void ResultBuilder::react() { +#if defined(CATCH_CONFIG_FAST_COMPILE) + if (m_shouldDebugBreak) { + /////////////////////////////////////////////////////////////////// + // To inspect the state during test, you need to go one level up the callstack + // To go back to the test and change execution, jump over the throw statement + /////////////////////////////////////////////////////////////////// + CATCH_BREAK_INTO_DEBUGGER(); + } +#endif + if( m_shouldThrow ) + throw Catch::TestFailureException(); + } + + bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } + bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } + + AssertionResult ResultBuilder::build() const + { + return build( *this ); + } + + // CAVEAT: The returned AssertionResult stores a pointer to the argument expr, + // a temporary DecomposedExpression, which in turn holds references to + // operands, possibly temporary as well. + // It should immediately be passed to handleResult; if the expression + // needs to be reported, its string expansion must be composed before + // the temporaries are destroyed. + AssertionResult ResultBuilder::build( DecomposedExpression const& expr ) const + { + assert( m_data.resultType != ResultWas::Unknown ); + AssertionResultData data = m_data; + + if(m_usedStream) + data.message = m_stream().oss.str(); + data.decomposedExpression = &expr; // for lazy reconstruction + return AssertionResult( m_assertionInfo, data ); + } + + void ResultBuilder::reconstructExpression( std::string& dest ) const { + dest = capturedExpressionWithSecondArgument(m_assertionInfo.capturedExpression, m_assertionInfo.secondArg); + } + + void ResultBuilder::setExceptionGuard() { + m_guardException = true; + } + void ResultBuilder::unsetExceptionGuard() { + m_guardException = false; + } + +} // end namespace Catch + +// #included from: catch_tag_alias_registry.hpp +#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + Option TagAliasRegistry::find( std::string const& alias ) const { + std::map::const_iterator it = m_registry.find( alias ); + if( it != m_registry.end() ) + return it->second; + else + return Option(); + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); + it != itEnd; + ++it ) { + std::size_t pos = expandedTestSpec.find( it->first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + it->second.tag + + expandedTestSpec.substr( pos + it->first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { + + if( !startsWith( alias, "[@" ) || !endsWith( alias, ']' ) ) { + std::ostringstream oss; + oss << Colour( Colour::Red ) + << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" + << Colour( Colour::FileName ) + << lineInfo << '\n'; + throw std::domain_error( oss.str().c_str() ); + } + if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { + std::ostringstream oss; + oss << Colour( Colour::Red ) + << "error: tag alias, \"" << alias << "\" already registered.\n" + << "\tFirst seen at " + << Colour( Colour::Red ) << find(alias)->lineInfo << '\n' + << Colour( Colour::Red ) << "\tRedefined at " + << Colour( Colour::FileName) << lineInfo << '\n'; + throw std::domain_error( oss.str().c_str() ); + } + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + + ITagAliasRegistry const& ITagAliasRegistry::get() { + return getRegistryHub().getTagAliasRegistry(); + } + + RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { + getMutableRegistryHub().registerTagAlias( alias, tag, lineInfo ); + } + +} // end namespace Catch + +// #included from: catch_matchers_string.hpp + +namespace Catch { +namespace Matchers { + + namespace StdString { + + CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string CasedString::adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + } + std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : std::string(); + } + + StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) + : m_comparator( comparator ), + m_operation( operation ) { + } + + std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; + } + + EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} + + bool EqualsMatcher::match( std::string const& source ) const { + return m_comparator.adjustString( source ) == m_comparator.m_str; + } + + ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} + + bool ContainsMatcher::match( std::string const& source ) const { + return contains( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} + + bool StartsWithMatcher::match( std::string const& source ) const { + return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} + + bool EndsWithMatcher::match( std::string const& source ) const { + return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + } // namespace StdString + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + +} // namespace Matchers +} // namespace Catch +// #included from: ../reporters/catch_reporter_multi.hpp +#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED + +namespace Catch { + +class MultipleReporters : public SharedImpl { + typedef std::vector > Reporters; + Reporters m_reporters; + +public: + void add( Ptr const& reporter ) { + m_reporters.push_back( reporter ); + } + +public: // IStreamingReporter + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporters[0]->getPreferences(); + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->noMatchingTestCases( spec ); + } + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunStarting( testRunInfo ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupStarting( groupInfo ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseStarting( testInfo ); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionStarting( sectionInfo ); + } + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->assertionStarting( assertionInfo ); + } + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + bool clearBuffer = false; + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + clearBuffer |= (*it)->assertionEnded( assertionStats ); + return clearBuffer; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->sectionEnded( sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testGroupEnded( testGroupStats ); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->testRunEnded( testRunStats ); + } + + virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); + it != itEnd; + ++it ) + (*it)->skipTest( testInfo ); + } + + virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { + return this; + } + +}; + +Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { + Ptr resultingReporter; + + if( existingReporter ) { + MultipleReporters* multi = existingReporter->tryAsMulti(); + if( !multi ) { + multi = new MultipleReporters; + resultingReporter = Ptr( multi ); + if( existingReporter ) + multi->add( existingReporter ); + } + else + resultingReporter = existingReporter; + multi->add( additionalReporter ); + } + else + resultingReporter = additionalReporter; + + return resultingReporter; +} + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_xml.hpp +#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED + +// #included from: catch_reporter_bases.hpp +#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + namespace { + // Because formatting using c++ streams is stateful, drop down to C is required + // Alternatively we could use stringstream, but its performance is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; + + // Save previous errno, to prevent sprintf from overwriting it + ErrnoGuard guard; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); + } + } + + struct StreamingReporterBase : SharedImpl { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual ~StreamingReporterBase() CATCH_OVERRIDE; + + virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { + currentTestRunInfo = _testRunInfo; + } + virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { + currentGroupInfo = _groupInfo; + } + + virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { + currentTestCaseInfo = _testInfo; + } + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_sectionStack.push_back( _sectionInfo ); + } + + virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + } + virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { + currentGroupInfo.reset(); + } + virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + Ptr m_config; + std::ostream& stream; + + LazyStat currentTestRunInfo; + LazyStat currentGroupInfo; + LazyStat currentTestCaseInfo; + + std::vector m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + struct CumulativeReporterBase : SharedImpl { + template + struct Node : SharedImpl<> { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + typedef std::vector > ChildNodes; + T value; + ChildNodes children; + }; + struct SectionNode : SharedImpl<> { + explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} + virtual ~SectionNode(); + + bool operator == ( SectionNode const& other ) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == ( Ptr const& other ) const { + return operator==( *other ); + } + + SectionStats stats; + typedef std::vector > ChildSections; + typedef std::vector Assertions; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() ( Ptr const& node ) const { + return ((node->stats.sectionInfo.name == m_other.name) && + (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); + } + private: + void operator=( BySectionInfo const& ); + SectionInfo const& m_other; + }; + + typedef Node TestCaseNode; + typedef Node TestGroupNode; + typedef Node TestRunNode; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + } + ~CumulativeReporterBase(); + + virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { + return m_reporterPrefs; + } + + virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} + virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} + + virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + Ptr node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = new SectionNode( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + SectionNode::ChildSections::const_iterator it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = new SectionNode( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = node; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back( assertionStats ); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression( sectionNode.assertions.back().assertionResult ); + return true; + } + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + assert( !m_sectionStack.empty() ); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + Ptr node = new TestCaseNode( testCaseStats ); + assert( m_sectionStack.size() == 0 ); + node->children.push_back( m_rootSection ); + m_testCases.push_back( node ); + m_rootSection.reset(); + + assert( m_deepestSection ); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + Ptr node = new TestGroupNode( testGroupStats ); + node->children.swap( m_testCases ); + m_testGroups.push_back( node ); + } + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + Ptr node = new TestRunNode( testRunStats ); + node->children.swap( m_testGroups ); + m_testRuns.push_back( node ); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} + + virtual void prepareExpandedExpression( AssertionResult& result ) const { + if( result.isOk() ) + result.discardDecomposedExpression(); + else + result.expandDecomposedExpression(); + } + + Ptr m_config; + std::ostream& stream; + std::vector m_assertions; + std::vector > > m_sections; + std::vector > m_testCases; + std::vector > m_testGroups; + + std::vector > m_testRuns; + + Ptr m_rootSection; + Ptr m_deepestSection; + std::vector > m_sectionStack; + ReporterPreferences m_reporterPrefs; + + }; + + template + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + struct TestEventListenerBase : StreamingReporterBase { + TestEventListenerBase( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} + virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { + return false; + } + }; + +} // end namespace Catch + +// #included from: ../internal/catch_reporter_registrars.hpp +#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED + +namespace Catch { + + template + class LegacyReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new LegacyReporterAdapter( new T( config ) ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + LegacyReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ReporterRegistrar { + + class ReporterFactory : public SharedImpl { + + // *** Please Note ***: + // - If you end up here looking at a compiler error because it's trying to register + // your custom reporter class be aware that the native reporter interface has changed + // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via + // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. + // However please consider updating to the new interface as the old one is now + // deprecated and will probably be removed quite soon! + // Please contact me via github if you have any questions at all about this. + // In fact, ideally, please contact me anyway to let me know you've hit this - as I have + // no idea who is actually using custom reporters at all (possibly no-one!). + // The new interface is designed to minimise exposure to interface changes in the future. + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + + virtual std::string getDescription() const { + return T::getDescription(); + } + }; + + public: + + ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); + } + }; + + template + class ListenerRegistrar { + + class ListenerFactory : public SharedImpl { + + virtual IStreamingReporter* create( ReporterConfig const& config ) const { + return new T( config ); + } + virtual std::string getDescription() const { + return std::string(); + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( new ListenerFactory() ); + } + }; +} + +#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ + namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ + namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } + +// Deprecated - use the form without INTERNAL_ +#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ + namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } + +#define CATCH_REGISTER_LISTENER( listenerType ) \ + namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } + +// #included from: ../internal/catch_xmlwriter.hpp +#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace Catch { + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void encodeTo( std::ostream& os ) const { + + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t i = 0; i < m_str.size(); ++ i ) { + char c = m_str[i]; + switch( c ) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) + os << ">"; + else + os << c; + break; + + case '\"': + if( m_forWhat == ForAttributes ) + os << """; + else + os << c; + break; + + default: + // Escape control chars - based on contribution by @espenalb in PR #465 and + // by @mrpi PR #588 + if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) { + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast( c ); + } + else + os << c; + } + } + } + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + ScopedElement( ScopedElement const& other ) + : m_writer( other.m_writer ){ + other.m_writer = CATCH_NULL; + } + + ~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + ScopedElement& writeText( std::string const& text, bool indent = true ) { + m_writer->writeText( text, indent ); + return *this; + } + + template + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer; + }; + + XmlWriter() + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( Catch::cout() ) + { + writeDeclaration(); + } + + XmlWriter( std::ostream& os ) + : m_tagIsOpen( false ), + m_needsNewline( false ), + m_os( os ) + { + writeDeclaration(); + } + + ~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + ScopedElement scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } + else { + m_os << m_indent << ""; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + template + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + std::ostringstream oss; + oss << attribute; + return writeAttribute( name, oss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + m_os << m_indent; + m_os << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + XmlWriter& writeComment( std::string const& text ) { + ensureTagClosed(); + m_os << m_indent << ""; + m_needsNewline = true; + return *this; + } + + void writeStylesheetRef( std::string const& url ) { + m_os << "\n"; + } + + XmlWriter& writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; + } + + void ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } + } + + private: + XmlWriter( XmlWriter const& ); + void operator=( XmlWriter const& ); + + void writeDeclaration() { + m_os << "\n"; + } + + void newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } + + bool m_tagIsOpen; + bool m_needsNewline; + std::vector m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +} + +namespace Catch { + class XmlReporter : public StreamingReporterBase { + public: + XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_xml(_config.stream()), + m_sectionDepth( 0 ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~XmlReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results as an XML document"; + } + + virtual std::string getStylesheetRef() const { + return std::string(); + } + + void writeSourceInfo( SourceLineInfo const& sourceInfo ) { + m_xml + .writeAttribute( "filename", sourceInfo.file ) + .writeAttribute( "line", sourceInfo.line ); + } + + public: // StreamingReporterBase + + virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { + StreamingReporterBase::noMatchingTestCases( s ); + } + + virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testRunStarting( testInfo ); + std::string stylesheetRef = getStylesheetRef(); + if( !stylesheetRef.empty() ) + m_xml.writeStylesheetRef( stylesheetRef ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ) + .writeAttribute( "name", trim( testInfo.name ) ) + .writeAttribute( "description", testInfo.description ) + .writeAttribute( "tags", testInfo.tagsAsString ); + + writeSourceInfo( testInfo.lineInfo ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); + } + + virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ) + .writeAttribute( "description", sectionInfo.description ); + writeSourceInfo( sectionInfo.lineInfo ); + m_xml.ensureTagClosed(); + } + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } + + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + + AssertionResult const& result = assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + if( includeResults || result.getResultType() == ResultWas::Warning ) { + // Print any info messages in tags. + for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); + it != itEnd; + ++it ) { + if( it->type == ResultWas::Info && includeResults ) { + m_xml.scopedElement( "Info" ) + .writeText( it->message ); + } else if ( it->type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( it->message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return true; + + // Print the expression if there is one. + if( result.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", result.succeeded() ) + .writeAttribute( "type", result.getTestMacroName() ); + + writeSourceInfo( result.getSourceInfo() ); + + m_xml.scopedElement( "Original" ) + .writeText( result.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( result.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( result.getResultType() ) { + case ResultWas::ThrewException: + m_xml.startElement( "Exception" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement( "FatalErrorCondition" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( result.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement( "Failure" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + default: + break; + } + + if( result.hasExpression() ) + m_xml.endElement(); + + return true; + } + + virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + if( !testCaseStats.stdOut.empty() ) + m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); + if( !testCaseStats.stdErr.empty() ) + m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); + + m_xml.endElement(); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_junit.hpp +#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED + +#include + +namespace Catch { + + namespace { + std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm* timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + + } + + class JunitReporter : public CumulativeReporterBase { + public: + JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ), + unexpectedExceptions( 0 ), + m_okToFail( false ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + virtual ~JunitReporter() CATCH_OVERRIDE; + + static std::string getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} + + virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { + suiteTimer.start(); + stdOutForSuite.str(""); + stdErrForSuite.str(""); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + virtual void testCaseStarting( TestCaseInfo const& testCaseInfo ) CATCH_OVERRIDE { + m_okToFail = testCaseInfo.okToFail(); + } + virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { + stdOutForSuite << testCaseStats.stdOut; + stdErrForSuite << testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + virtual void testRunEndedCumulative() CATCH_OVERRIDE { + xml.endElement(); + } + + void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "timestamp", getCurrentTimestamp() ); + + // Write test cases + for( TestGroupNode::ChildNodes::const_iterator + it = groupNode.children.begin(), itEnd = groupNode.children.end(); + it != itEnd; + ++it ) + writeTestCase( **it ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); + } + + void writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + if( rootSection.childSections.empty() ) + className = "global"; + } + writeSection( className, "", rootSection ); + } + + void writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode ) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + '/' + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); + } + for( SectionNode::ChildSections::const_iterator + it = sectionNode.childSections.begin(), + itEnd = sectionNode.childSections.end(); + it != itEnd; + ++it ) + if( className.empty() ) + writeSection( name, "", **it ); + else + writeSection( className, name, **it ); + } + + void writeAssertions( SectionNode const& sectionNode ) { + for( SectionNode::Assertions::const_iterator + it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); + it != itEnd; + ++it ) + writeAssertion( *it ); + } + void writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpandedExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + std::ostringstream oss; + if( !result.getMessage().empty() ) + oss << result.getMessage() << '\n'; + for( std::vector::const_iterator + it = stats.infoMessages.begin(), + itEnd = stats.infoMessages.end(); + it != itEnd; + ++it ) + if( it->type == ResultWas::Info ) + oss << it->message << '\n'; + + oss << "at " << result.getSourceInfo(); + xml.writeText( oss.str(), false ); + } + } + + XmlWriter xml; + Timer suiteTimer; + std::ostringstream stdOutForSuite; + std::ostringstream stdErrForSuite; + unsigned int unexpectedExceptions; + bool m_okToFail; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_console.hpp +#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED + +#include +#include +#include + +namespace Catch { + + struct ConsoleReporter : StreamingReporterBase { + ConsoleReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_headerPrinted( false ) + {} + + virtual ~ConsoleReporter() CATCH_OVERRIDE; + static std::string getDescription() { + return "Reports test results as plain lines of text"; + } + + virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { + } + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { + AssertionResult const& result = _assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return false; + + lazyPrint(); + + AssertionPrinter printer( stream, _assertionStats, includeResults ); + printer.print(); + stream << std::endl; + return true; + } + + virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting( _sectionInfo ); + } + virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { + if( _sectionStats.missingAssertions ) { + lazyPrint(); + Colour colour( Colour::ResultError ); + if( m_sectionStack.size() > 1 ) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if( m_config->showDurations() == ShowDurations::Always ) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + if( m_headerPrinted ) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded( _sectionStats ); + } + + virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { + StreamingReporterBase::testCaseEnded( _testCaseStats ); + m_headerPrinted = false; + } + virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { + if( currentGroupInfo.used ) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals( _testGroupStats.totals ); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded( _testGroupStats ); + } + virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { + printTotalsDivider( _testRunStats.totals ); + printTotals( _testRunStats.totals ); + stream << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ), + stats( _stats ), + result( _stats.assertionResult ), + colour( Colour::None ), + message( result.getMessage() ), + messages( _stats.infoMessages ), + printInfoMessages( _printInfoMessages ) + { + switch( result.getResultType() ) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } + else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if( _stats.infoMessages.size() == 1 ) + messageLabel = "with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with "; + if (_stats.infoMessages.size() == 1) + messageLabel += "message"; + if (_stats.infoMessages.size() > 1) + messageLabel += "messages"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if( _stats.infoMessages.size() == 1 ) + messageLabel = "explicitly with message"; + if( _stats.infoMessages.size() > 1 ) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if( stats.totals.assertions.total() > 0 ) { + if( result.isOk() ) + stream << '\n'; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } + else { + stream << '\n'; + } + printMessage(); + } + + private: + void printResultType() const { + if( !passOrFail.empty() ) { + Colour colourGuard( colour ); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if( result.hasExpression() ) { + Colour colourGuard( Colour::OriginalExpression ); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + stream << "with expansion:\n"; + Colour colourGuard( Colour::ReconstructedExpression ); + stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << '\n'; + } + } + void printMessage() const { + if( !messageLabel.empty() ) + stream << messageLabel << ':' << '\n'; + for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); + it != itEnd; + ++it ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || it->type != ResultWas::Info ) + stream << Text( it->message, TextAttributes().setIndent(2) ) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector messages; + bool printInfoMessages; + }; + + void lazyPrint() { + + if( !currentTestRunInfo.used ) + lazyPrintRunInfo(); + if( !currentGroupInfo.used ) + lazyPrintGroupInfo(); + + if( !m_headerPrinted ) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } + } + void lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour( Colour::SecondaryText ); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion() << " host application.\n" + << "Run with -? for options\n\n"; + + if( m_config->rngSeed() != 0 ) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; + } + void lazyPrintGroupInfo() { + if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { + printClosedHeader( "Group: " + currentGroupInfo->name ); + currentGroupInfo.used = true; + } + } + void printTestCaseAndSectionHeader() { + assert( !m_sectionStack.empty() ); + printOpenHeader( currentTestCaseInfo->name ); + + if( m_sectionStack.size() > 1 ) { + Colour colourGuard( Colour::Headers ); + + std::vector::const_iterator + it = m_sectionStack.begin()+1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for( ; it != itEnd; ++it ) + printHeaderString( it->name, 2 ); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + if( !lineInfo.empty() ){ + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard( Colour::FileName ); + stream << lineInfo << '\n'; + } + stream << getLineOfChars<'.'>() << '\n' << std::endl; + } + + void printClosedHeader( std::string const& _name ) { + printOpenHeader( _name ); + stream << getLineOfChars<'.'>() << '\n'; + } + void printOpenHeader( std::string const& _name ) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard( Colour::Headers ); + printHeaderString( _name ); + } + } + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { + std::size_t i = _string.find( ": " ); + if( i != std::string::npos ) + i+=2; + else + i = 0; + stream << Text( _string, TextAttributes() + .setIndent( indent+i) + .setInitialIndent( indent ) ) << '\n'; + } + + struct SummaryColumn { + + SummaryColumn( std::string const& _label, Colour::Code _colour ) + : label( _label ), + colour( _colour ) + {} + SummaryColumn addRow( std::size_t count ) { + std::ostringstream oss; + oss << count; + std::string row = oss.str(); + for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { + while( it->size() < row.size() ) + *it = ' ' + *it; + while( it->size() > row.size() ) + row = ' ' + row; + } + rows.push_back( row ); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector rows; + + }; + + void printTotals( Totals const& totals ) { + if( totals.testCases.total() == 0 ) { + stream << Colour( Colour::Warning ) << "No tests ran\n"; + } + else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { + stream << Colour( Colour::ResultSuccess ) << "All tests passed"; + stream << " (" + << pluralise( totals.assertions.passed, "assertion" ) << " in " + << pluralise( totals.testCases.passed, "test case" ) << ')' + << '\n'; + } + else { + + std::vector columns; + columns.push_back( SummaryColumn( "", Colour::None ) + .addRow( totals.testCases.total() ) + .addRow( totals.assertions.total() ) ); + columns.push_back( SummaryColumn( "passed", Colour::Success ) + .addRow( totals.testCases.passed ) + .addRow( totals.assertions.passed ) ); + columns.push_back( SummaryColumn( "failed", Colour::ResultError ) + .addRow( totals.testCases.failed ) + .addRow( totals.assertions.failed ) ); + columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) + .addRow( totals.testCases.failedButOk ) + .addRow( totals.assertions.failedButOk ) ); + + printSummaryRow( "test cases", columns, 0 ); + printSummaryRow( "assertions", columns, 1 ); + } + } + void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { + for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { + std::string value = it->rows[row]; + if( it->label.empty() ) { + stream << label << ": "; + if( value != "0" ) + stream << value; + else + stream << Colour( Colour::Warning ) << "- none -"; + } + else if( value != "0" ) { + stream << Colour( Colour::LightGrey ) << " | "; + stream << Colour( it->colour ) + << value << ' ' << it->label; + } + } + stream << '\n'; + } + + static std::size_t makeRatio( std::size_t number, std::size_t total ) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; + return ( ratio == 0 && number > 0 ) ? 1 : ratio; + } + static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { + if( i > j && i > k ) + return i; + else if( j > k ) + return j; + else + return k; + } + + void printTotalsDivider( Totals const& totals ) { + if( totals.testCases.total() > 0 ) { + std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); + std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); + std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); + while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )++; + while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) + findMax( failedRatio, failedButOkRatio, passedRatio )--; + + stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); + stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); + if( totals.testCases.allPassed() ) + stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); + else + stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); + } + else { + stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); + } + stream << '\n'; + } + void printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; + } + + private: + bool m_headerPrinted; + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) + +} // end namespace Catch + +// #included from: ../reporters/catch_reporter_compact.hpp +#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED + +namespace Catch { + + struct CompactReporter : StreamingReporterBase { + + CompactReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ) + {} + + virtual ~CompactReporter(); + + static std::string getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + virtual ReporterPreferences getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + virtual void noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + virtual void assertionStarting( AssertionInfo const& ) {} + + virtual bool assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + virtual void sectionEnded(SectionStats const& _sectionStats) CATCH_OVERRIDE { + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + } + + virtual void testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( _testRunStats.totals ); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + private: + class AssertionPrinter { + void operator= ( AssertionPrinter const& ); + public: + AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) + : stream( _stream ) + , stats( _stats ) + , result( _stats.assertionResult ) + , messages( _stats.infoMessages ) + , itMessage( _stats.infoMessages.begin() ) + , printInfoMessages( _printInfoMessages ) + {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch( result.getResultType() ) { + case ResultWas::Ok: + printResultType( Colour::ResultSuccess, passedString() ); + printOriginalExpression(); + printReconstructedExpression(); + if ( ! result.hasExpression() ) + printRemainingMessages( Colour::None ); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if( result.isOk() ) + printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); + else + printResultType( Colour::Error, failedString() ); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType( Colour::Error, failedString() ); + printIssue( "unexpected exception with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType( Colour::Error, failedString() ); + printIssue( "fatal error condition with message:" ); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType( Colour::Error, failedString() ); + printIssue( "expected exception, got none" ); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType( Colour::None, "info" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType( Colour::None, "warning" ); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType( Colour::Error, failedString() ); + printIssue( "explicitly" ); + printRemainingMessages( Colour::None ); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType( Colour::Error, "** internal error **" ); + break; + } + } + + private: + // Colour::LightGrey + + static Colour::Code dimColour() { return Colour::FileName; } + +#ifdef CATCH_PLATFORM_MAC + static const char* failedString() { return "FAILED"; } + static const char* passedString() { return "PASSED"; } +#else + static const char* failedString() { return "failed"; } + static const char* passedString() { return "passed"; } +#endif + + void printSourceInfo() const { + Colour colourGuard( Colour::FileName ); + stream << result.getSourceInfo() << ':'; + } + + void printResultType( Colour::Code colour, std::string const& passOrFail ) const { + if( !passOrFail.empty() ) { + { + Colour colourGuard( colour ); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue( std::string const& issue ) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if( result.hasExpression() ) { + stream << ';'; + { + Colour colour( dimColour() ); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if( result.hasExpression() ) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if( result.hasExpandedExpression() ) { + { + Colour colour( dimColour() ); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if ( itMessage != messages.end() ) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages( Colour::Code colour = dimColour() ) { + if ( itMessage == messages.end() ) + return; + + // using messages.end() directly yields compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); + + { + Colour colourGuard( colour ); + stream << " with " << pluralise( N, "message" ) << ':'; + } + + for(; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if( printInfoMessages || itMessage->type != ResultWas::Info ) { + stream << " '" << itMessage->message << '\''; + if ( ++itMessage != itEnd ) { + Colour colourGuard( dimColour() ); + stream << " and"; + } + } + } + } + + private: + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; + }; + + // Colour, message variants: + // - white: No tests ran. + // - red: Failed [both/all] N test cases, failed [both/all] M assertions. + // - white: Passed [both/all] N test cases (no assertions). + // - red: Failed N tests cases, failed M assertions. + // - green: Passed [both/all] N tests cases with M assertions. + + std::string bothOrAll( std::size_t count ) const { + return count == 1 ? std::string() : count == 2 ? "both " : "all " ; + } + + void printTotals( const Totals& totals ) const { + if( totals.testCases.total() == 0 ) { + stream << "No tests ran."; + } + else if( totals.testCases.failed == totals.testCases.total() ) { + Colour colour( Colour::ResultError ); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll( totals.assertions.failed ) : std::string(); + stream << + "Failed " << bothOrAll( totals.testCases.failed ) + << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << qualify_assertions_failed << + pluralise( totals.assertions.failed, "assertion" ) << '.'; + } + else if( totals.assertions.total() == 0 ) { + stream << + "Passed " << bothOrAll( totals.testCases.total() ) + << pluralise( totals.testCases.total(), "test case" ) + << " (no assertions)."; + } + else if( totals.assertions.failed ) { + Colour colour( Colour::ResultError ); + stream << + "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " + "failed " << pluralise( totals.assertions.failed, "assertion" ) << '.'; + } + else { + Colour colour( Colour::ResultSuccess ); + stream << + "Passed " << bothOrAll( totals.testCases.passed ) + << pluralise( totals.testCases.passed, "test case" ) << + " with " << pluralise( totals.assertions.passed, "assertion" ) << '.'; + } + } + }; + + INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch + +namespace Catch { + // These are all here to avoid warnings about not having any out of line + // virtual methods + NonCopyable::~NonCopyable() {} + IShared::~IShared() {} + IStream::~IStream() CATCH_NOEXCEPT {} + FileStream::~FileStream() CATCH_NOEXCEPT {} + CoutStream::~CoutStream() CATCH_NOEXCEPT {} + DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} + StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} + IContext::~IContext() {} + IResultCapture::~IResultCapture() {} + ITestCase::~ITestCase() {} + ITestCaseRegistry::~ITestCaseRegistry() {} + IRegistryHub::~IRegistryHub() {} + IMutableRegistryHub::~IMutableRegistryHub() {} + IExceptionTranslator::~IExceptionTranslator() {} + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} + IReporter::~IReporter() {} + IReporterFactory::~IReporterFactory() {} + IReporterRegistry::~IReporterRegistry() {} + IStreamingReporter::~IStreamingReporter() {} + AssertionStats::~AssertionStats() {} + SectionStats::~SectionStats() {} + TestCaseStats::~TestCaseStats() {} + TestGroupStats::~TestGroupStats() {} + TestRunStats::~TestRunStats() {} + CumulativeReporterBase::SectionNode::~SectionNode() {} + CumulativeReporterBase::~CumulativeReporterBase() {} + + StreamingReporterBase::~StreamingReporterBase() {} + ConsoleReporter::~ConsoleReporter() {} + CompactReporter::~CompactReporter() {} + IRunner::~IRunner() {} + IMutableContext::~IMutableContext() {} + IConfig::~IConfig() {} + XmlReporter::~XmlReporter() {} + JunitReporter::~JunitReporter() {} + TestRegistry::~TestRegistry() {} + FreeFunctionTestCase::~FreeFunctionTestCase() {} + IGeneratorInfo::~IGeneratorInfo() {} + IGeneratorsForTest::~IGeneratorsForTest() {} + WildcardPattern::~WildcardPattern() {} + TestSpec::Pattern::~Pattern() {} + TestSpec::NamePattern::~NamePattern() {} + TestSpec::TagPattern::~TagPattern() {} + TestSpec::ExcludedPattern::~ExcludedPattern() {} + Matchers::Impl::MatcherUntypedBase::~MatcherUntypedBase() {} + + void Config::dummy() {} + + namespace TestCaseTracking { + ITracker::~ITracker() {} + TrackerBase::~TrackerBase() {} + SectionTracker::~SectionTracker() {} + IndexTracker::~IndexTracker() {} + } +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif + +#ifdef CATCH_CONFIG_MAIN +// #included from: internal/catch_default_main.hpp +#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED + +#ifndef __OBJC__ + +#if defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) +// Standard C/C++ Win32 Unicode wmain entry point +extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +#else +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { +#endif + + int result = Catch::Session().run( argc, argv ); + return ( result < 0xff ? result : 0xff ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char* const*)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return ( result < 0xff ? result : 0xff ); +} + +#endif // __OBJC__ + +#endif + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +////// + +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#if defined(CATCH_CONFIG_FAST_COMPILE) +#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) +#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) +#else +#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, expr ) +#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) +#endif + +#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) + +#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) +#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) + +#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) + +#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#if defined(CATCH_CONFIG_FAST_COMPILE) +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#else +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) +#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << Catch::toString(msg) ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS + #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) + #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) + #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) + #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) + #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) + #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) + #define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#else + #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) + #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) + #define CATCH_FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) + #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) +#endif +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) +#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) +#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) +#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) +#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) +#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#if defined(CATCH_CONFIG_FAST_COMPILE) +#define REQUIRE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE", Catch::ResultDisposition::Normal, expr ) +#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST_NO_TRY( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) + +#else +#define REQUIRE( expr ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, expr ) +#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, expr ) +#endif + +#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", expr ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, expr ) + +#define CHECK( expr ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, expr ) +#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, expr ) + +#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", expr ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, expr ) + +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#if defined(CATCH_CONFIG_FAST_COMPILE) +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT_NO_TRY( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#else +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif + +#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) +#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) +#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << Catch::toString(msg) ) + +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#else +#define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) + #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) + #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) + #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) + #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) + #define FAIL( msg ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, msg ) + #define FAIL_CHECK( msg ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, msg ) + #define SUCCEED( msg ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, msg ) +#endif +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) + +#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) +#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) + +#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#ifdef CATCH_CONFIG_VARIADIC_MACROS +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#else +#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) +#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) +#endif +#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) +#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) +#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) +#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) +#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) + +using Catch::Detail::Approx; + +// #included from: internal/catch_reenable_warnings.h + +#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + diff --git a/Searching/binary search/c/test/main_test.cc b/Searching/binary search/c/test/main_test.cc new file mode 100644 index 000000000..0c7c351f4 --- /dev/null +++ b/Searching/binary search/c/test/main_test.cc @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include "catch.hpp" diff --git a/Searching/binary search/cpp/binarySearch.cpp b/Searching/binary search/cpp/binarySearch.cpp index 93614ae1d..69904db8e 100644 --- a/Searching/binary search/cpp/binarySearch.cpp +++ b/Searching/binary search/cpp/binarySearch.cpp @@ -1,37 +1,24 @@ -#include +#include using namespace std; -string binarySearch(vector a,int l,int r,int num) -{ - int mid = l + (r-l)/2; - if(r>=l) - { - if(a[mid] == num) - return("Found"); - else if(a[mid] > num) - return(binarySearch(a,l,mid-1,num)); - else - return(binarySearch(a,mid+1,r,num)); - +bool BinarySearch(int arr[], int n, int k){ + int s=0;int e=n-1; + while (s<=e){ + int mid=(s+e)/2; + if (arr[mid]==k) return true; + if (arr[mid]>n; + int arr[n]; + cout<<"Enter The elements of the array"<>arr[i]; + cout<<"Enter the key value you want to search"<>k; + if (BinarySearch(arr,n,k)) cout<<"Element is found"<>n; - cout<<"Enter Elements"; - int i = n; - vector a; - while(i--) - { - int t; - cin>>t; - a.push_back(t); - } - int num; - cout<<"enter number to search"; - cin>>num; - cout<=l) + { + int mid = l + (r - l)/2; + + // If the element is present at the + // middle itself + if (arr[mid] == x) + return mid; + + // If element is smaller than mid, then + // it can only be present in left subarray + if (arr[mid] > x) + return binarySearch(arr, l, mid-1, x); + + // Else the element can only be present + // in right subarray + return binarySearch(arr, mid+1, r, x); + } + + // We reach here when element is not present + // in array + return -1; + } + + // Driver method to test above + public static void main(String args[]) + { + BinarySearch ob = new BinarySearch(); + int arr[] = {2,3,4,10,40}; + int n = arr.length; + int x = 10; + int result = ob.binarySearch(arr,0,n-1,x); + if (result == -1) + System.out.println("Element not present"); + else + System.out.println("Element found at index " + + result); + } +} \ No newline at end of file diff --git a/Searching/binary search/matlab/binary-search.mat b/Searching/binary search/matlab/binary-search.mat new file mode 100644 index 000000000..0aea67b02 --- /dev/null +++ b/Searching/binary search/matlab/binary-search.mat @@ -0,0 +1,20 @@ +function mid = binarySearchRec(list,value,low,high) + + if( high < low ) + mid = []; + return + end + + mid = floor((low + high)/2); + + if( list(mid) > value ) + mid = binarySearchRec(list,value,low,mid-1); + return + elseif( list(mid) < value ) + mid = binarySearchRec(list,value,mid+1,high); + return + else + return + end + +end diff --git a/Searching/binary search/perl/binarySearch-iterative.pl b/Searching/binary search/perl/binarySearch-iterative.pl new file mode 100644 index 000000000..4623a9839 --- /dev/null +++ b/Searching/binary search/perl/binarySearch-iterative.pl @@ -0,0 +1,18 @@ +//iterative method + +sub binary_search { + my ($array_ref, $value, $left, $right) = @_; + while ($left <= $right) { + my $middle = int(($right + $left) >> 1); + if ($value == $array_ref->[$middle]) { + return $middle; + } + elsif ($value < $array_ref->[$middle]) { + $right = $middle - 1; + } + else { + $left = $middle + 1; + } + } + return -1; +} diff --git a/Searching/binary search/perl/binarySearch-recursive.pl b/Searching/binary search/perl/binarySearch-recursive.pl new file mode 100644 index 000000000..53b63ad0a --- /dev/null +++ b/Searching/binary search/perl/binarySearch-recursive.pl @@ -0,0 +1,16 @@ +//using recursive + +sub binary_search { + my ($array_ref, $value, $left, $right) = @_; + return -1 if ($right < $left); + my $middle = int(($right + $left) >> 1); + if ($value == $array_ref->[$middle]) { + return $middle; + } + elsif ($value < $array_ref->[$middle]) { + binary_search($array_ref, $value, $left, $middle - 1); + } + else { + binary_search($array_ref, $value, $middle + 1, $right); + } +} diff --git a/Searching/binary search/python/binarySearch.py b/Searching/binary search/python/binarySearch.py index 8559d43ed..b03d40d88 100644 --- a/Searching/binary search/python/binarySearch.py +++ b/Searching/binary search/python/binarySearch.py @@ -9,9 +9,31 @@ def binarySearch(A,num,l,r): return binarySearch(A,num,mid+1,r) else: return("Not Found") + + +#this non recursive function will return index as well. e is the element to be searched +def non_recursive_binary_search(a,n,e): + i,j=0,n-1 + while i<=j: + m=(i+j)//2 + if a[m]==e: + return 'found at index ' + str(m) + + #seach in the right half + if e>a[m]: + i=m+1 + + #search in the left half + else: + j=m-1 + + return 'Element not found' print("Enter the elements of the array in a single line: ") a = list(map(int,input().split())) num = int(input("Enter the number you want to search")) -print(binarySearch(a,num,0,len(a))) \ No newline at end of file +print(binarySearch(a,num,0,len(a))) + +#test the non recursive function and see if both the functions yield the same result +print(non_recursive_binary_search(a,len(a),num)) diff --git a/Searching/binary search/rust/binary_search.rs b/Searching/binary search/rust/binary_search.rs new file mode 100644 index 000000000..495b192ba --- /dev/null +++ b/Searching/binary search/rust/binary_search.rs @@ -0,0 +1,32 @@ +fn binary_search(v : &Vec, value : i32) -> i32{ + let mut low = 0; + let mut high = v.len()-1; + + while low <= high { + + let mid = (low+high)/2; + + if value > v[mid]{ + low = mid+1; + } + else if value < v[mid] { + high = mid-1; + }else { + return mid as i32; + } + } + i32::MAX +} + + +fn main() { + let mut v: Vec = vec![1, 2, 3, 4, 5, 9, 0]; + v.sort(); + let index = binary_search(&v, 9); + if index != i32::MAX{ + println!("index of element is -> {}", index); + } + else { + println!("Element not found"); + } +} diff --git a/Selection Algorithms/Quick_Select/cpp/quick_select.cpp b/Selection Algorithms/Quick_Select/cpp/quick_select.cpp new file mode 100644 index 000000000..8037c7f37 --- /dev/null +++ b/Selection Algorithms/Quick_Select/cpp/quick_select.cpp @@ -0,0 +1,77 @@ +#include +#define ll long long +using namespace std; + +//Linear time partition algo +ll partition_(ll arr[], ll i, ll j, ll p){ + //arr[i..k..j] + ll l, r; + l=r=0; + std::swap(arr[l], arr[p]); + p=0; + while(r <= j){ + if(arr[r]< arr[p]){ + std::swap(arr[++l], arr[r]); + } + r++; + } + std::swap(arr[l], arr[p]); + return l; +} + +//In-place algorithm +//requires O(1) memory if compiler is tail call optimized +//selection of pivot is randomized to avoid worst case pivot selection +//leading ot amortized T.C = O(n) +ll quick_select(ll arr[], ll size_arr, ll N){ + N-=1;//Nth smallest will be at index N-1 + ll i = 0; + ll j = size_arr - 1; + + while(i <= j){ + srand(time(NULL)); + ll p = rand()%(j-i+1)+i; + p = partition_(arr, i, j, p); + if(p == N){ + break; + } + else if(p < N){ + i = p+1; + } + else{ + j = p-1; + } + } + return arr[N]; +} +//run a comparison b/w randomized version of quickselect and +//inbuilt nth_element which utilizes +//intro select algorithm +int main(int argc, char const *argv[]){ + ll size_arr; + ll ans; + clock_t t; + cin>>size_arr; + ll arr[size_arr]; + std::vector v; + for(ll i=0; i>arr[i]; + v.push_back(arr[i]); + } + ll N; + cin>>N; + t = clock(); + ans = quick_select(arr, size_arr, N); + t = clock() - t; + cout<<"quickselect returned in "<<((float)t/CLOCKS_PER_SEC)<<" seconds: "; + cout<(ref T lhs, ref T rhs) + { + T temp; + temp = lhs; + lhs = rhs; + rhs = temp; + } + + // To check if array is sorted or not + public static bool isSorted(int[] a, int n) + { + int i = 0; + while(ia[i+1]) + return false; + i++; + } + return true; + } + + // To generate permuatation of the array + public static void shuffle(int[] a, int n) + { + Random rnd = new Random(); + for (int i=0; i < n; i++) + Swap(ref a[i], ref a[rnd.Next(0,n)]); + } + + // Sorts array a[0..n-1] using Bogo sort + public static void bogosort(int[] a, int n) + { + // if array is not sorted then shuffle + // the array again + while ( !isSorted(a, n) ) + shuffle(a, n); + } + + // prints the array + public static void printArray(int[] a, int n) + { + for (int i=0; i + #include + + template + void bogosort(std::vector& array) + { + while (! is_sorted(array)) + std::random_shuffle(array.begin(), array.end()); + } + + template + bool is_sorted(const std::vector& array) + { + for (typename std::vector::size_type i = 1; i < array.size(); ++i) + if (array[i] < array[i-1]) return false; + return true; + } \ No newline at end of file diff --git a/Sorting/Bogosort/C/Bogosort.c b/Sorting/Bogosort/C/Bogosort.c new file mode 100644 index 000000000..6416e0176 --- /dev/null +++ b/Sorting/Bogosort/C/Bogosort.c @@ -0,0 +1,37 @@ +#include +#include +#include + +bool is_sorted(int *a, int n) +{ + while ( --n >= 1 ) { + if ( a[n] < a[n-1] ) return false; + } + return true; +} + +void shuffle(int *a, int n) +{ + int i, t, r; + for(i=0; i < n; i++) { + t = a[i]; + r = rand() % n; + a[i] = a[r]; + a[r] = t; + } +} + +void bogosort(int *a, int n) +{ + while ( !is_sorted(a, n) ) shuffle(a, n); +} + +int main() +{ + int numbers[] = { 1, 10, 9, 7, 3, 0 }; + int i; + + bogosort(numbers, 6); + for (i=0; i < 6; i++) printf("%d ", numbers[i]); + printf("\n"); +} \ No newline at end of file diff --git a/Sorting/Bogosort/Java/Bogosort.java b/Sorting/Bogosort/Java/Bogosort.java new file mode 100644 index 000000000..1ecc81db2 --- /dev/null +++ b/Sorting/Bogosort/Java/Bogosort.java @@ -0,0 +1,59 @@ +// Java Program to implement BogoSort +public class BogoSort +{ + // Sorts array a[0..n-1] using Bogo sort + void bogoSort(int[] a) + { + // if array is not sorted then shuffle the + // array again + while (isSorted(a) == false) + shuffle(a); + } + + // To generate permuatation of the array + void shuffle(int[] a) + { + // Math.random() returns a double positive + // value, greater than or equal to 0.0 and + // less than 1.0. + for (int i=1; i <= n; i++) + swap(a, i, (int)(Math.random()*i)); + } + + // Swapping 2 elements + void swap(int[] a, int i, int j) + { + int temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } + + // To check if array is sorted or not + boolean isSorted(int[] a) + { + for (int i=1; i=proto[max-1]) then + teste:=false; + end; + + begin + randomize; {*Inicializa o gerador de numeros aleatrios *} + writeln('Escreva abaixo os ', max,' elementos do vetor:'); + for i:=1 to max do + begin + read(lista[i]); + lista1[i]:=lista[i]; + end; + for i:=1 to max do {*Escreve o vetor recebido *} + write(lista1[i],' '); + writeln; + while teste(lista1) do {*Enquanto o vetor nao esta ordenado...*} + begin + j:=true; + for i:=1 to max do {*Inicializa o vetor auxiliar *} + lista1[i]:=0; + for i:=1 to max do {* Este loop preenche aleatoriamente o vetor auxiliar *} + begin + j:=true; + while j do {* Este while garante que nenhum dado ser sobrescrito *} + begin + pos:= random(max)+1; {* Gera posio aleatria *} + if lista1[pos]=0 then {*Garante que a posio no est ocupada *} + begin + lista1[pos]:=lista[i]; + j:=false; + end; + end; + end; + for i:=1 to max do {* Imprime na tela a tentativa *} + write(lista1[i],' '); + writeln; + end; + write('A LISTA FOI ORDENADA!'); + end. \ No newline at end of file diff --git a/Sorting/MonkeySort/python/monkeysort.py b/Sorting/Bogosort/Python/bogosort.py similarity index 100% rename from Sorting/MonkeySort/python/monkeysort.py rename to Sorting/Bogosort/Python/bogosort.py diff --git a/Sorting/Bogosort/Ruby/bogosort.rb b/Sorting/Bogosort/Ruby/bogosort.rb new file mode 100644 index 000000000..4875698a4 --- /dev/null +++ b/Sorting/Bogosort/Ruby/bogosort.rb @@ -0,0 +1,21 @@ +# BogoSort also known as permutation sort, stupid sort, slow sort, shotgun sort +# or monkey sort is a particularly ineffective algorithm based on generate and +# test paradigm. The algorithm successively generates permutations of its input +# until it finds one that is sorted. + +def sorted?(ary) + 0.upto(ary.size - 2).all? { |n| ary[n] <= ary[n + 1] } +end + +def bogosort(ary) + until sorted?(ary) + ary.shuffle! + end + + ary +end + +test_array = Array.new(10) { rand(100) } +bogosort(test_array) +puts "Sorted array: #{test_array}" +puts "Correct? #{test_array == test_array.sort}" \ No newline at end of file diff --git a/Sorting/bubbleSort/brainfuck/bubble_sort.bf b/Sorting/Bubble Sort/Brainfuck/bubble_sort.bf similarity index 100% rename from Sorting/bubbleSort/brainfuck/bubble_sort.bf rename to Sorting/Bubble Sort/Brainfuck/bubble_sort.bf diff --git a/Sorting/Bubble Sort/C Sharp/BubbleSort.cs b/Sorting/Bubble Sort/C Sharp/BubbleSort.cs new file mode 100644 index 000000000..ce09d4b5c --- /dev/null +++ b/Sorting/Bubble Sort/C Sharp/BubbleSort.cs @@ -0,0 +1,52 @@ +/* + * Bubble Sort implementation in C#; + * Author : Lucas Madeira; + * Input : Array elements; + * Output : Sorted array elements; +*/ + +using System; + +namespace BubbleSort +{ + class Program + { + static void Main(string[] args) + { + int[] array = { 3, 2, 6, 7, 1, 5, 8, 4, 9, 0 }; + + Console.WriteLine("Before: "); + PrintArray(array); + + BubbleSort(array); + + Console.WriteLine("\n\nAfter: "); + PrintArray(array); + + Console.WriteLine("\n\nPress any key to exit."); + Console.ReadKey(); + } + + public static void BubbleSort(int[] array) + { + for (int i = 0; i < array.Length - 1; i++) + { + for (int j = 0; j < array.Length - (i + 1); j++) + { + if (array[j] > array[j + 1]) + { + int aux = array[j]; + array[j] = array[j + 1]; + array[j + 1] = aux; + } + } + } + } + + public static void PrintArray(int[] array) + { + foreach (int value in array) + Console.Write(" {0}", value); + } + } +} diff --git a/Sorting/bubbleSort/C/bubble.c b/Sorting/Bubble Sort/C/bubble_sort.c similarity index 100% rename from Sorting/bubbleSort/C/bubble.c rename to Sorting/Bubble Sort/C/bubble_sort.c diff --git a/Sorting/Bubble Sort/CPP/bubble_sort.cpp b/Sorting/Bubble Sort/CPP/bubble_sort.cpp new file mode 100644 index 000000000..e6b324101 --- /dev/null +++ b/Sorting/Bubble Sort/CPP/bubble_sort.cpp @@ -0,0 +1,47 @@ +/* Bubble Sort implementation in C++ + * Author : Manvi Gupta + * Input : array length and elements + * Output : Sorted array elements + */ +#include +using namespace std; + +int n; + +void bubble_Sort(int a[]) +{ + + for(int i=0; i a[j+1]) + { + swap(a[j+1], a[j]); + flag = 1; // Set flag = 1 to signify that the element is sorted.c + } + } + if (flag == 0) + { + // No elements have been swapped, which means that the array is sorted. End the algorithm. + break; + } + } +} + +int main() +{ + cout<<"Enter the size of the array"<> n; + int a[n]; + cout<<"Enter the elements of the array"<> a[i]; + bubble_Sort(a); + cout<<"The sorted array is : "< data[j + 1]) { + int temp = data[j]; + data[j] = data[j + 1]; + data[j + 1] = temp; + } + } + } + + return data; + } +} diff --git a/Sorting/Bubble Sort/Java/BubbleSortDynamic.java b/Sorting/Bubble Sort/Java/BubbleSortDynamic.java new file mode 100644 index 000000000..6e4736022 --- /dev/null +++ b/Sorting/Bubble Sort/Java/BubbleSortDynamic.java @@ -0,0 +1,37 @@ +#Blazing21 +#Indonesia + +import java.util.Arrays; +import java.util.Scanner; + +public class BubbleSort { + public static void main(String[] args) { + Scanner scan = new Scanner(System.in); + int a; + System.out.print( "Range data : "); + a=scan.nextInt(); + int[] data = new int[a]; + for( int i = 0; i < data.length; i++ ){ + System.out.print("data-" + i + ": "); + data[i] = scan.nextInt(); + } + System.out.println("Before Sort: " + Arrays.toString(data)); + data = sort(data); + System.out.println("After Sort: " + Arrays.toString(data)); + } + + // bubble sort algorithm + public static int[] sort(int[] data) { + for (int i = 0; i < data.length; i++) { + for (int j = 0; j < data.length - 1; j++) { + if (data[j] > data[j + 1]) { + int temp = data[j]; + data[j] = data[j + 1]; + data[j + 1] = temp; + } + } + } + + return data; + } +} diff --git a/Sorting/bubbleSort/js/bubble_sort.js b/Sorting/Bubble Sort/Javascript/bubble_sort.js similarity index 100% rename from Sorting/bubbleSort/js/bubble_sort.js rename to Sorting/Bubble Sort/Javascript/bubble_sort.js diff --git a/Sorting/Bubble Sort/Julia/bubble-sort.jl b/Sorting/Bubble Sort/Julia/bubble-sort.jl new file mode 100644 index 000000000..95b39f2bd --- /dev/null +++ b/Sorting/Bubble Sort/Julia/bubble-sort.jl @@ -0,0 +1,28 @@ +# Bubble Sort is the simplest sorting algorithm that works by +# repeatedly swapping the adjacent elements if they are in wrong order. + +function swap!{T}(x::AbstractArray{T}, a::T, b::T) + + tmp = x[a] + x[a] = x[b] + x[b] = tmp + return x + +end + +function bubblesort!{T}(x::AbstractArray{T}) + + for i in 2:length(x) + for j in 1:length(x)-1 + if x[j] > x[j+1] + swap!(x, j, j+1) + end + end + end + + return x +end + +x = [10,2,5,1,3,0] + +println(bubblesort!(x)) \ No newline at end of file diff --git a/Sorting/Bubble Sort/PHP/bubble-sort.php b/Sorting/Bubble Sort/PHP/bubble-sort.php new file mode 100644 index 000000000..3e62f9a45 --- /dev/null +++ b/Sorting/Bubble Sort/PHP/bubble-sort.php @@ -0,0 +1,28 @@ + $array[$y + 1]) { + $temp = $array[$y]; + $array[$y] = $array[$y + 1]; + $array[$y + 1] = $temp; + } +} + echo ("After #" . $x . " run: "); + print_array($array); + } +} +function print_array($array) { + for ($x = 0;$x < count($array);$x++) { + echo ($array[$x] . " "); + } + echo ("\n"); +} + +$array = [34, 22, 1, 8, 2, 13]; +echo "Original Array: "; +print_array($array); +bubble_sort($array); + +?> diff --git a/Sorting/bubbleSort/perl/bubbleSort.pl b/Sorting/Bubble Sort/Perl/bubble_sort.pl similarity index 100% rename from Sorting/bubbleSort/perl/bubbleSort.pl rename to Sorting/Bubble Sort/Perl/bubble_sort.pl diff --git a/Sorting/bubbleSort/python/bubble_sort.py b/Sorting/Bubble Sort/Python/bubble_sort.py similarity index 74% rename from Sorting/bubbleSort/python/bubble_sort.py rename to Sorting/Bubble Sort/Python/bubble_sort.py index d69e69c02..b4ff6e7b7 100644 --- a/Sorting/bubbleSort/python/bubble_sort.py +++ b/Sorting/Bubble Sort/Python/bubble_sort.py @@ -1,6 +1,7 @@ +# the main() function is the place from which the code starts executing def main(): print("Result-> "+str(bubble_sort([2, 4, 9, 3, 1, 6, 5, 7]))) - +# A function that uses bubble sort to sort integers provided def bubble_sort(arr): while True: sorted = True @@ -15,4 +16,4 @@ def bubble_sort(arr): break if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/Sorting/bubbleSort/python/bubble_sort_recursively.py b/Sorting/Bubble Sort/Python/bubble_sort_recursively.py similarity index 100% rename from Sorting/bubbleSort/python/bubble_sort_recursively.py rename to Sorting/Bubble Sort/Python/bubble_sort_recursively.py diff --git a/Sorting/bubbleSort/Ruby/bubble_sort.rb b/Sorting/Bubble Sort/Ruby/bubble_sort.rb similarity index 100% rename from Sorting/bubbleSort/Ruby/bubble_sort.rb rename to Sorting/Bubble Sort/Ruby/bubble_sort.rb diff --git a/Sorting/Bubble Sort/Rust/bubble_sort.rs b/Sorting/Bubble Sort/Rust/bubble_sort.rs new file mode 100644 index 000000000..e9a39b7be --- /dev/null +++ b/Sorting/Bubble Sort/Rust/bubble_sort.rs @@ -0,0 +1,21 @@ +pub fn bubble_sort(array: &mut [T]) { + for i in 0..array.len() { + let mut swapped: bool = false; + for j in 0..array.len() { + if array[j] > array[i] { + array.swap(j,i); + swapped = true; + } + } + + if !swapped { + break + } + } +} + +pub fn main() { + let mut array: [i32; 9] = [2,4,7,3,9,23,1,56,12]; + bubble_sort(&mut array); + assert_eq!(array, [1,2,3,4,7,9,12,23,56]); +} diff --git a/Sorting/bubbleSort/Swift/bubblesort.swift b/Sorting/Bubble Sort/Swift/bubble_sort.swift similarity index 100% rename from Sorting/bubbleSort/Swift/bubblesort.swift rename to Sorting/Bubble Sort/Swift/bubble_sort.swift diff --git a/Sorting/Bubble Sort/perl/bublesort.pl b/Sorting/Bubble Sort/perl/bublesort.pl new file mode 100644 index 000000000..4e6429f68 --- /dev/null +++ b/Sorting/Bubble Sort/perl/bublesort.pl @@ -0,0 +1,8 @@ +# Sorts an array in place +sub bubble_sort { + for my $i (0 .. $#_){ + for my $j ($i + 1 .. $#_){ + $_[$j] < $_[$i] and @_[$i, $j] = @_[$j, $i]; + } + } +} diff --git a/Sorting/Bucket Sort/CPP/bucketsort.cpp b/Sorting/Bucket Sort/C++/bucket_sort.cpp similarity index 100% rename from Sorting/Bucket Sort/CPP/bucketsort.cpp rename to Sorting/Bucket Sort/C++/bucket_sort.cpp diff --git a/Sorting/Bucket Sort/Java/BucketSort.java b/Sorting/Bucket Sort/Java/bucket_sort.java similarity index 100% rename from Sorting/Bucket Sort/Java/BucketSort.java rename to Sorting/Bucket Sort/Java/bucket_sort.java diff --git a/Sorting/Bucket Sort/Javascript/bucket_sort.js b/Sorting/Bucket Sort/Javascript/bucket_sort.js new file mode 100644 index 000000000..7bcb77c79 --- /dev/null +++ b/Sorting/Bucket Sort/Javascript/bucket_sort.js @@ -0,0 +1,62 @@ +/* +Wikipedia says: Bucket sort, or bin sort, is a sorting algorithm that works by distributing the +elements of an array into a number of buckets. Each bucket is then sorted individually, either using +a different sorting algorithm, or by recursively applying the bucket sorting algorithm. It is a +distribution sort, and is a cousin of radix sort in the most to least significant digit flavour. +Bucket sort is a generalization of pigeonhole sort. Bucket sort can be implemented with comparisons +and therefore can also be considered a comparison sort algorithm. The computational complexity estimates +involve the number of buckets. + +Time Complexity of Solution: +Best Case O(n); Average Case O(n); Worst Case O(n) + +*/ +function bucketSort(list, size){ + + if(undefined === size){ + size = 5; + } + if(list.length === 0){ + return list; + } + let min = list[0]; + let max = list[0]; + // find min and max + for(let iList = 0; iList < list.length; iList++){ + + if(list[iList] < min){ + min = list[iList]; + } else if(list[iList] > max){ + max = list[iList]; + } + } + // how many buckets we need + let count = Math.floor((max - min) / size) + 1; + + // create buckets + let buckets = []; + for(let iCount = 0; iCount < count; iCount++){ + buckets.push([]); + } + + // bucket fill + for(let iBucket = 0; iBucket < list.length; iBucket++){ + let key = Math.floor((list[iBucket] - min) / size); + buckets[key].push(list[iBucket]) + } + let sorted = []; + // now sort every bucket and merge it to the sorted list + for(let iBucket = 0; iBucket < buckets.length; iBucket++){ + let arr = buckets[iBucket].sort(); + for(let iSorted = 0; iSorted < arr.length; iSorted++){ + sorted.push(arr[iSorted]); + } + } + return sorted; +} +let arrOrignal = [5, 6, 7, 8, 1, 2, 12, 14]; +//Array before Sort +console.log(arrOrignal); +arrSorted = bucketSort(arrOrignal); +//Array after sort +console.log(arrSorted); \ No newline at end of file diff --git a/Sorting/Cocktail/C++/Cocktail.cpp b/Sorting/Cocktail/C++/Cocktail.cpp new file mode 100644 index 000000000..76762283d --- /dev/null +++ b/Sorting/Cocktail/C++/Cocktail.cpp @@ -0,0 +1,80 @@ +#include +#include + +const int EL_COUNT = 77, LLEN = 11; + +class cocktailSort +{ +public: + void sort( int* arr, int len ) + { + bool notSorted = true; + while( notSorted ) + { + notSorted = false; + for( int a = 0; a < len - 1; a++ ) + { + if( arr[a] > arr[a + 1] ) + { + sSwap( arr[a], arr[a + 1] ); + notSorted = true; + } + } + + if( !notSorted ) break; + notSorted = false; + + for( int a = len - 1; a > 0; a-- ) + { + if( arr[a - 1] > arr[a] ) + { + sSwap( arr[a], arr[a - 1] ); + notSorted = true; + } + } + } + } + +private: + void sSwap( int& a, int& b ) + { + int t = a; + a = b; b = t; + } +}; + +int main( int argc, char* argv[] ) +{ + srand( GetTickCount() ); + cocktailSort cs; + int arr[EL_COUNT]; + + for( int x = 0; x < EL_COUNT; x++ ) + arr[x] = rand() % EL_COUNT + 1; + + std::cout << "Original: " << std::endl << "==========" << std::endl; + for( int x = 0; x < EL_COUNT; x += LLEN ) + { + for( int s = x; s < x + LLEN; s++ ) + std::cout << arr[s] << ", "; + + std::cout << std::endl; + } + + //DWORD now = GetTickCount(); + cs.sort( arr, EL_COUNT ); + //now = GetTickCount() - now; + + std::cout << std::endl << std::endl << "Sorted: " << std::endl << "========" << std::endl; + for( int x = 0; x < EL_COUNT; x += LLEN ) + { + for( int s = x; s < x + LLEN; s++ ) + std::cout << arr[s] << ", "; + + std::cout << std::endl; + } + + std::cout << std::endl << std::endl << std::endl << std::endl; + //std::cout << now << std::endl << std::endl; + return 0; +} diff --git a/Sorting/Cocktail/C/Cocktail.c b/Sorting/Cocktail/C/Cocktail.c new file mode 100644 index 000000000..44690eef9 --- /dev/null +++ b/Sorting/Cocktail/C/Cocktail.c @@ -0,0 +1,39 @@ +#include + +// can be any swap function. This swap is optimized for numbers. +void swap(int *x, int *y) { + if(x == y) + return; + *x ^= *y; + *y ^= *x; + *x ^= *y; +} +void cocktailsort(int *a, size_t n) { + while(1) { + // packing two similar loops into one + char flag; + size_t start[2] = {1, n - 1}, + end[2] = {n, 0}, + inc[2] = {1, -1}; + for(int it = 0; it < 2; ++it) { + flag = 1; + for(int i = start[it]; i != end[it]; i += inc[it]) + if(a[i - 1] > a[i]) { + swap(a + i - 1, a + i); + flag = 0; + } + if(flag) + return; + } + } +} + +int main(void) { + int a[] = { 5, -1, 101, -4, 0, 1, 8, 6, 2, 3 }; + size_t n = sizeof(a)/sizeof(a[0]); + + cocktailsort(a, n); + for (size_t i = 0; i < n; ++i) + printf("%d ", a[i]); + return 0; +} diff --git a/Sorting/Cocktail/FORTRAN/Cocktail.f90 b/Sorting/Cocktail/FORTRAN/Cocktail.f90 new file mode 100644 index 000000000..afc169a93 --- /dev/null +++ b/Sorting/Cocktail/FORTRAN/Cocktail.f90 @@ -0,0 +1,44 @@ +PROGRAM COCKTAIL + IMPLICIT NONE + + INTEGER :: intArray(10) = (/ 4, 9, 3, -2, 0, 7, -5, 1, 6, 8 /) + + WRITE(*,"(A,10I5)") "Unsorted array:", intArray + CALL Cocktail_sort(intArray) + WRITE(*,"(A,10I5)") "Sorted array :", intArray + +CONTAINS + + SUBROUTINE Cocktail_sort(a) + INTEGER, INTENT(IN OUT) :: a(:) + INTEGER :: i, bottom, top, temp + LOGICAL :: swapped + + bottom = 1 + top = SIZE(a) - 1 + DO WHILE (bottom < top ) + swapped = .FALSE. + DO i = bottom, top + IF (array(i) > array(i+1)) THEN + temp = array(i) + array(i) = array(i+1) + array(i+1) = temp + swapped = .TRUE. + END IF + END DO + IF (.NOT. swapped) EXIT + DO i = top, bottom + 1, -1 + IF (array(i) < array(i-1)) THEN + temp = array(i) + array(i) = array(i-1) + array(i-1) = temp + swapped = .TRUE. + END IF + END DO + IF (.NOT. swapped) EXIT + bottom = bottom + 1 + top = top - 1 + END DO + END SUBROUTINE Cocktail_sort + +END PROGRAM COCKTAIL diff --git a/Sorting/Cocktail/R/Cocktail.R b/Sorting/Cocktail/R/Cocktail.R new file mode 100644 index 000000000..8b3eab334 --- /dev/null +++ b/Sorting/Cocktail/R/Cocktail.R @@ -0,0 +1,35 @@ +cocktailsort <- function(x) +{ + lenx <- length(x) + repeat + { + swapped <- FALSE + for(i in 1:(lenx-1)) + { + if(x[i] > x[i+1]) + { + temp <- x[i] + x[i] <- x[i+1] + x[i+1] <- temp + swapped <- TRUE + } + } + if(!swapped) break + + swapped <- FALSE + for(i in (lenx-1):1) + { + if(x[i] > x[i+1]) + { + temp <- x[i] + x[i] <- x[i+1] + x[i+1] <- temp + swapped <- TRUE + } + } + if(!swapped) break + } + x +} + +print(cocktailsort(c(5, -1, 101, -4, 0, 1, 8, 6, 2, 3))) diff --git a/Sorting/Cocktail/py3_cocktail_sort.py b/Sorting/Cocktail/py3_cocktail_sort.py new file mode 100644 index 000000000..55b9c88d1 --- /dev/null +++ b/Sorting/Cocktail/py3_cocktail_sort.py @@ -0,0 +1,17 @@ +def cocktail_sort(a): + for i in range(len(a)//2): + swap = False + for j in range(1+i, len(a)-i): + if a[j] < a[j-1]: + a[j], a[j-1] = a[j-1], a[j] + swap = True + if not swap: + break + swap = False + for j in range(len(a)-i-1, i, -1): + if a[j] < a[j-1]: + a[j], a[j-1] = a[j-1], a[j] + swap = True + if not swap: + break + return a diff --git a/Sorting/Comb Sort/Ruby/comb_sort.rb b/Sorting/Comb Sort/Ruby/comb_sort.rb new file mode 100644 index 000000000..e1989e118 --- /dev/null +++ b/Sorting/Comb Sort/Ruby/comb_sort.rb @@ -0,0 +1,40 @@ +# Comb Sort is mainly an improvement over Bubble Sort. Bubble sort always +# compares adjacent values. So all inversions are removed one by one. Comb Sort +# improves on Bubble Sort by using gap of size more than 1. The gap starts with +# a large value and shrinks by a factor of 1.3 in every iteration until it +# reaches the value 1. Thus Comb Sort removes more than one inversion counts +# with one swap and performs better than Bublle Sort. +# +# More on: https://www.geeksforgeeks.org/comb-sort/ +# Illustration gif: https://upload.wikimedia.org/wikipedia/commons/4/46/Comb_sort_demo.gif + +def combsort(array, shrink = 1.247330950103979) + sorted = array.dup + gap = array.size + swapped = false + + until gap == 1 && !swapped + gap = (gap / shrink).to_i + gap = 1 if gap < 1 + + swapped = false + + gap.upto(sorted.size - 1) do |i| + next if sorted[i - gap] <= sorted[i] + + sorted[i - gap], sorted[i] = sorted[i], sorted[i - gap] + swapped = true + end + end + + sorted +end + +# Test case +if $PROGRAM_NAME == __FILE__ + unsorted = Array.new(20) { rand(10_000) } + sorted = combsort(unsorted) + puts "Sorting: #{unsorted}" + puts "Sorted: #{sorted}" + puts "Correct? #{sorted == unsorted.sort}" +end diff --git a/Sorting/Counting Sort/C/Counting_sort.c b/Sorting/Counting Sort/C/Counting_sort.c new file mode 100644 index 000000000..ba9972488 --- /dev/null +++ b/Sorting/Counting Sort/C/Counting_sort.c @@ -0,0 +1,38 @@ +#include +#include +#include +void countingSort(int* arr, int highest, int num){ + int* Count = (int*)malloc(highest*sizeof(int)); + int* Sorted = (int*)malloc(num*sizeof(int)); + for(int i=0;ik) + k = arr[i]; + } + countingSort(arr,k,n); + return 0; +} diff --git a/Sorting/Counting Sort/CPP/counting_sort.cpp b/Sorting/Counting Sort/CPP/counting_sort.cpp new file mode 100644 index 000000000..d77307fe8 --- /dev/null +++ b/Sorting/Counting Sort/CPP/counting_sort.cpp @@ -0,0 +1,26 @@ +#include +using namespace std; +#define ll long long +int main(){ + ll n; + cout<<"Enter size of array:\n"; + cin>>n; + vector a(n,0); + cout<<"enter the array:\n"; + for(int i=0;i>a[i]; + } + //frequency array: + ll m = *max_element(a.begin(),a.end()); + vector fre(m+1,0); + for(int i=0;i 0; c-- { + a[z] = i + aMin + z++ + } + } +} diff --git a/Sorting/countsort/Java/CountingSort.java b/Sorting/Counting Sort/Java/counting_sort.java similarity index 100% rename from Sorting/countsort/Java/CountingSort.java rename to Sorting/Counting Sort/Java/counting_sort.java diff --git a/Sorting/countsort/js/countSort.js b/Sorting/Counting Sort/Javascript/counting_sort.js similarity index 100% rename from Sorting/countsort/js/countSort.js rename to Sorting/Counting Sort/Javascript/counting_sort.js diff --git a/Sorting/countsort/python/countsort.py b/Sorting/Counting Sort/Python/counting_sort.py similarity index 100% rename from Sorting/countsort/python/countsort.py rename to Sorting/Counting Sort/Python/counting_sort.py diff --git a/Sorting/Counting Sort/Ruby/countSort.rb b/Sorting/Counting Sort/Ruby/countSort.rb new file mode 100644 index 000000000..bcce4aff1 --- /dev/null +++ b/Sorting/Counting Sort/Ruby/countSort.rb @@ -0,0 +1,18 @@ +class Array + def counting_sort! + replace counting_sort + end + + def counting_sort + min, max = minmax + count = Array.new(max - min + 1, 0) + each {|number| count[number - min] += 1} + (min..max).each_with_object([]) {|i, ary| ary.concat([i] * count[i - min])} + end + end + + ary = [9,7,10,2,9,7,4,3,10,2,7,10,2,1,3,8,7,3,9,5,8,5,1,6,3,7,5,4,6,9,9,6,6,10,2,4,5,2,8,2,2,5,2,9,3,3,5,7,8,4] + p ary.counting_sort.join(",") + + p ary = Array.new(20){rand(-10..10)} + p ary.counting_sort diff --git a/Sorting/Counting Sort/Rust/counting-sort.rs b/Sorting/Counting Sort/Rust/counting-sort.rs new file mode 100644 index 000000000..dd0b01382 --- /dev/null +++ b/Sorting/Counting Sort/Rust/counting-sort.rs @@ -0,0 +1,63 @@ +/// Counting sort + +/// * `arr` - Collection of value to be sorted in place. + +/// * `min` - Lower bound of the integer range. + +/// * `max` - Upper bound of the integer range. + +/// * `key` - Function extracting key witn the integer range from elements. + +pub fn counting_sort(arr: &mut [T], min: usize, max: usize, key: F) +where + F: Fn(&T) -> usize, + T: Clone, +{ + let mut prefix_sums = { + // 1. Initialize the count array with default value 0. + let len = max - min; + let mut count_arr = Vec::with_capacity(len); + count_arr.resize(len, 0); + + // 2. Scan elements to collect counts. + for value in arr.iter() { + count_arr[key(value)] += 1; + } + + // 3. Calculate prefix sum. + count_arr + .into_iter() + .scan(0, |state, x| { + *state += x; + Some(*state - x) + }) + .collect::>() + }; + + // 4. Use prefix sum as index position of output element. + for value in arr.to_vec().iter() { + let index = key(value); + arr[prefix_sums[index]] = value.clone(); + prefix_sums[index] += 1; + } +} + +#[cfg(test)] + +mod base { + use super::*; + fn counting_sort_(arr: &mut [i32]) { + counting_sort(arr, 1, 10, |int| *int as usize); + } + base_cases!(counting_sort_); +} + +#[cfg(test)] + +mod stability { + use super::*; + fn counting_sort_(arr: &mut [(i32, i32)]) { + counting_sort(arr, 1, 10, |t| t.0 as usize); + } + stability_cases!(counting_sort_); +} diff --git a/Sorting/Cycle Sort/cppcylclesort.c b/Sorting/Cycle Sort/cppcylclesort.c new file mode 100644 index 000000000..40d97244f --- /dev/null +++ b/Sorting/Cycle Sort/cppcylclesort.c @@ -0,0 +1,78 @@ + +// C++ program to implement cycle sort +#include +using namespace std; + +// Function sort the array using Cycle sort +void cycleSort(int arr[], int n) +{ + // count number of memory writes + int writes = 0; + + // traverse array elements and put it to on + // the right place + for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) { + // initialize item as starting point + int item = arr[cycle_start]; + + // Find position where we put the item. We basically + // count all smaller elements on right side of item. + int pos = cycle_start; + for (int i = cycle_start + 1; i < n; i++) + if (arr[i] < item) + pos++; + + // If item is already in correct position + if (pos == cycle_start) + continue; + + // ignore all duplicate elements + while (item == arr[pos]) + pos += 1; + + // put the item to it's right position + if (pos != cycle_start) { + swap(item, arr[pos]); + writes++; + } + + // Rotate rest of the cycle + while (pos != cycle_start) { + pos = cycle_start; + + // Find position where we put the element + for (int i = cycle_start + 1; i < n; i++) + if (arr[i] < item) + pos += 1; + + // ignore all duplicate elements + while (item == arr[pos]) + pos += 1; + + // put the item to it's right position + if (item != arr[pos]) { + swap(item, arr[pos]); + writes++; + } + } + } + + // Number of memory writes or swaps + // cout << writes << endl ; +} + +// Driver program to test above function +/* +int main() +{ + int arr[] = { 1, 8, 3, 9, 10, 10, 2, 4 }; + int n = sizeof(arr) / sizeof(arr[0]); + cycleSort(arr, n); + + cout << "After sort : " << endl; + for (int i = 0; i < n; i++) + cout << arr[i] << " "; + return 0; +} +*/ + diff --git a/Sorting/Cycle Sort/pycycle.py b/Sorting/Cycle Sort/pycycle.py new file mode 100644 index 000000000..16864f2aa --- /dev/null +++ b/Sorting/Cycle Sort/pycycle.py @@ -0,0 +1,43 @@ +def cycle_sort(vector): + "Sort a vector in place and return the number of writes." + writes = 0 + + for cycleStart, item in enumerate(vector): + + pos = cycleStart + for item2 in vector[cycleStart + 1:]: + if item2 < item: + pos += 1 + + if pos == cycleStart: + continue + + while item == vector[pos]: + pos += 1 + vector[pos], item = item, vector[pos] + writes += 1 + + while pos != cycleStart: + + pos = cycleStart + for item2 in vector[cycleStart + 1:]: + if item2 < item: + pos += 1 + + while item == vector[pos]: + pos += 1 + vector[pos], item = item, vector[pos] + writes += 1 + + return writes + + +if __name__ == '__main__': + x = [0, 1, 2, 2, 2, 2, 1, 9, 3.5, 5, 8, 4, 7, 0, 6] + xcopy = x[::] + writes = cycle_sort(xcopy) + if xcopy != sorted(x): + print('Wrong order!') + else: + print('%r\nIs correctly sorted using cycleSort to' + '\n%r\nUsing %i writes.' % (x, xcopy, writes)) diff --git a/Sorting/Gnome Sort/Go/GnomeSort.go b/Sorting/Gnome Sort/Go/GnomeSort.go new file mode 100644 index 000000000..b5e01e5ec --- /dev/null +++ b/Sorting/Gnome Sort/Go/GnomeSort.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" +) + +func GnomeSort(slice []int) []int { + pos := 0 + for pos < len(slice) { + if pos == 0 || slice[pos] >= slice[pos-1] { + pos++ + } else { + tmp := slice[pos] + slice[pos] = slice[pos-1] + slice[pos-1] = tmp + pos-- + } + } + + return slice +} + +func main() { + slice := []int{43, 41, 82, 2, 16, 7} + fmt.Println(slice) + fmt.Println(GnomeSort(slice)) +} diff --git a/Sorting/Gnome Sort/Python/py3_gnome.py b/Sorting/Gnome Sort/Python/py3_gnome.py new file mode 100644 index 000000000..e0a872e45 --- /dev/null +++ b/Sorting/Gnome Sort/Python/py3_gnome.py @@ -0,0 +1,11 @@ +def gnome_sort(a): + i, j, size = 1, 2, len(a) + while i < size: + if a[i-1] <= a[i]: + i, j = j, j+1 + else: + a[i-1], a[i] = a[i], a[i-1] + i -= 1 + if i == 0: + i, j = j, j+1 + return a diff --git a/Sorting/Gnome Sort/Ruby/GnomeSort.rb b/Sorting/Gnome Sort/Ruby/GnomeSort.rb new file mode 100644 index 000000000..dbba47402 --- /dev/null +++ b/Sorting/Gnome Sort/Ruby/GnomeSort.rb @@ -0,0 +1,21 @@ +class Array + def gnomesort! + i, j = 1, 2 + while i < length + if self[i-1] <= self[i] + i, j = j, j+1 + else + self[i-1], self[i] = self[i], self[i-1] + i -= 1 + if i == 0 + i, j = j, j+1 + end + end + end + self + end + end + + + ary = [7,6,5,9,8,4,3,1,2,0] + ary.gnomesort! diff --git a/Sorting/Heap Sort/C Sharp/heapsort.cs b/Sorting/Heapsort/C Sharp/heapsort.cs similarity index 100% rename from Sorting/Heap Sort/C Sharp/heapsort.cs rename to Sorting/Heapsort/C Sharp/heapsort.cs diff --git a/Sorting/Heap Sort/cpp/a.out b/Sorting/Heapsort/C++/a.out old mode 100755 new mode 100644 similarity index 100% rename from Sorting/Heap Sort/cpp/a.out rename to Sorting/Heapsort/C++/a.out diff --git a/Sorting/Heap Sort/cpp/heapsort.cpp b/Sorting/Heapsort/C++/heapsort.cpp similarity index 100% rename from Sorting/Heap Sort/cpp/heapsort.cpp rename to Sorting/Heapsort/C++/heapsort.cpp diff --git a/Sorting/Heapsort/C/Heapsort.c b/Sorting/Heapsort/C/Heapsort.c new file mode 100644 index 000000000..0734d6081 --- /dev/null +++ b/Sorting/Heapsort/C/Heapsort.c @@ -0,0 +1,65 @@ +#include + +void create(int []); +void down_adjust(int [],int); + +void main() +{ + int heap[30],n,i,last,temp; + printf("Enter no. of elements:"); + scanf("%d",&n); + printf("\nEnter elements:"); + for(i=1;i<=n;i++) + scanf("%d",&heap[i]); + + //create a heap + heap[0]=n; + create(heap); + + //sorting + while(heap[0] > 1) + { + //swap heap[1] and heap[last] + last=heap[0]; + temp=heap[1]; + heap[1]=heap[last]; + heap[last]=temp; + heap[0]--; + down_adjust(heap,1); + } + + //print sorted data + printf("\nArray after sorting:\n"); + for(i=1;i<=n;i++) + printf("%d ",heap[i]); +} + +void create(int heap[]) +{ + int i,n; + n=heap[0]; //no. of elements + for(i=n/2;i>=1;i--) + down_adjust(heap,i); +} + +void down_adjust(int heap[],int i) +{ + int j,temp,n,flag=1; + n=heap[0]; + + while(2*i<=n && flag==1) + { + j=2*i; //j points to left child + if(j+1<=n && heap[j+1] > heap[j]) + j=j+1; + if(heap[i] > heap[j]) + flag=0; + else + { + temp=heap[i]; + heap[i]=heap[j]; + heap[j]=temp; + i=j; + } + } +} diff --git a/Sorting/Heapsort/Java/HeapSort.java b/Sorting/Heapsort/Java/HeapSort.java new file mode 100644 index 000000000..5482a6e5e --- /dev/null +++ b/Sorting/Heapsort/Java/HeapSort.java @@ -0,0 +1,74 @@ +// Java program for implementation of Heap Sort +public class HeapSort +{ + public void sort(int arr[]) + { + int n = arr.length; + + // Build heap (rearrange array) + for (int i = n / 2 - 1; i >= 0; i--) + heapify(arr, n, i); + + // One by one extract an element from heap + for (int i=n-1; i>=0; i--) + { + // Move current root to end + int temp = arr[0]; + arr[0] = arr[i]; + arr[i] = temp; + + // call max heapify on the reduced heap + heapify(arr, i, 0); + } + } + + // To heapify a subtree rooted with node i which is + // an index in arr[]. n is size of heap + void heapify(int arr[], int n, int i) + { + int largest = i; // Initialize largest as root + int l = 2*i + 1; // left = 2*i + 1 + int r = 2*i + 2; // right = 2*i + 2 + + // If left child is larger than root + if (l < n && arr[l] > arr[largest]) + largest = l; + + // If right child is larger than largest so far + if (r < n && arr[r] > arr[largest]) + largest = r; + + // If largest is not root + if (largest != i) + { + int swap = arr[i]; + arr[i] = arr[largest]; + arr[largest] = swap; + + // Recursively heapify the affected sub-tree + heapify(arr, n, largest); + } + } + + /* A utility function to print array of size n */ + static void printArray(int arr[]) + { + int n = arr.length; + for (int i=0; i=0;j--) + { + + if(arr[j]>swap) + { + + arr[j+1]=arr[j]; + arr[j]=swap; + + + } + + } + for(int k=0;k= 0 && (array[j] > temp); j--) { - array[j + 1] = array[j]; - } - array[j + 1] = temp; - } -} +function insertionSort (array) { + for (var i = 0; i < array.length; i++) { + var temp = array[i]; + for (var j = i - 1; j >= 0 && (array[j] > temp); j--) { + array[j + 1] = array[j]; + } + array[j + 1] = temp; + } +} diff --git a/Sorting/insertionSort/python/insertionSort.py b/Sorting/Insertion Sort/Python/insertion_sort.py similarity index 100% rename from Sorting/insertionSort/python/insertionSort.py rename to Sorting/Insertion Sort/Python/insertion_sort.py diff --git a/Sorting/Recursive Insertion Sort/python/recInsertSort.py b/Sorting/Insertion Sort/Python/insertion_sort_recursively.py similarity index 100% rename from Sorting/Recursive Insertion Sort/python/recInsertSort.py rename to Sorting/Insertion Sort/Python/insertion_sort_recursively.py diff --git a/Sorting/insertionSort/Ruby/insertion_sort.rb b/Sorting/Insertion Sort/Ruby/insertion_sort.rb similarity index 100% rename from Sorting/insertionSort/Ruby/insertion_sort.rb rename to Sorting/Insertion Sort/Ruby/insertion_sort.rb diff --git a/Sorting/Insertion Sort/Rust/insertion_sort.rs b/Sorting/Insertion Sort/Rust/insertion_sort.rs new file mode 100644 index 000000000..b56eb30da --- /dev/null +++ b/Sorting/Insertion Sort/Rust/insertion_sort.rs @@ -0,0 +1,17 @@ +pub fn insertion_sort(array: &mut [T]) { + for i in 0..values.len() { + for j in (0..i).rev() { + if values[j] >= values[j + 1] { + values.swap(j, j + 1); + } else { + break + } + } + } +} + +pub fn main() { + let mut array: [i32; 9] = [2,3,7,5,3,8,12,54,21]; + selection_sort(&mut array); + assert_eq!(array, [2,3,3,5,7,8,12,21,54]); +} diff --git a/Sorting/MergeSort/ada/merge_sort.adb b/Sorting/Merge Sort/Ada/merge_sort.adb similarity index 100% rename from Sorting/MergeSort/ada/merge_sort.adb rename to Sorting/Merge Sort/Ada/merge_sort.adb diff --git a/Sorting/Merge Sort/C++/mergeSort_linked_list.cpp b/Sorting/Merge Sort/C++/mergeSort_linked_list.cpp new file mode 100644 index 000000000..9deb8bf9a --- /dev/null +++ b/Sorting/Merge Sort/C++/mergeSort_linked_list.cpp @@ -0,0 +1,118 @@ +#include +#include + +using namespace std; + +typedef struct Node +{ + int data; + struct Node *next; +}node; + + +void print(node *ptr){ + while(ptr!=NULL){ + cout<data<<"->"; + ptr=ptr->next; + } + cout<data=num; + newnode->next=NULL; + return newnode; +} + +void insertList(node **ptr2head, node **ptr2tail, int num){ + node *tempnode=createNode(num); + + if(*ptr2head==NULL){ + *ptr2head=tempnode; + *ptr2tail=tempnode; + } + else{ + (*ptr2tail)->next=tempnode; + *ptr2tail=(*ptr2tail)->next; + } +} + +node *listMerge(node *ptr1, node *ptr2){ + node *head=NULL,*tail=NULL; + while(ptr1!=NULL || ptr2!=NULL){ + if(ptr1==NULL){ + tail->next=ptr2; + break; + } + else if(ptr2==NULL){ + tail->next=ptr1; + break; + } + else if(ptr1->data>ptr2->data){ + if(head==NULL){ + head=tail=ptr2; + } + else{ + tail->next=ptr2; + tail=tail->next; + } + ptr2=ptr2->next; + tail->next=NULL; + } + else{ + if(head==NULL){ + head=tail=ptr1; + } + else{ + tail->next=ptr1; + tail=tail->next; + } + ptr1=ptr1->next; + tail->next=NULL; + } + } + return head; +} + +node *MergeSortLinked(node *ptr){ + if(ptr->next==NULL) + return ptr; + + node *ptr1=ptr,*ptr2=ptr; + + while(ptr2->next!=NULL && ptr2->next->next!=NULL){ + ptr1=ptr1->next; + ptr2=ptr2->next->next; + } + node *temp=ptr1->next; + ptr1->next=NULL; + ptr1=temp; + + ptr=MergeSortLinked(ptr); + ptr1=MergeSortLinked(ptr1); + ptr=listMerge(ptr,ptr1); + return ptr; +} + + +int main(){ + int n,max; + cin>>n>>max; //input + + node *head=NULL,*tail=NULL; + + default_random_engine gen; + uniform_int_distribution dist(1,max); + + for(int i=0; i +#include + +// Merges two subarrays of arr[]. +// First subarray is arr[l..m] +// Second subarray is arr[m+1..r] +void merge(int arr[], int l, int m, int r) +{ + int i, j, k; + int n1 = m - l + 1; + int n2 = r - m; + + /* create temp arrays */ + int L[n1], R[n2]; + + /* Copy data to temp arrays L[] and R[] */ + for (i = 0; i < n1; i++) + L[i] = arr[l + i]; + for (j = 0; j < n2; j++) + R[j] = arr[m + 1+ j]; + + /* Merge the temp arrays back into arr[l..r]*/ + i = 0; // Initial index of first subarray + j = 0; // Initial index of second subarray + k = l; // Initial index of merged subarray + while (i < n1 && j < n2) + { + if (L[i] <= R[j]) + { + arr[k] = L[i]; + i++; + } + else + { + arr[k] = R[j]; + j++; + } + k++; + } + + /* Copy the remaining elements of L[], if there + are any */ + while (i < n1) + { + arr[k] = L[i]; + i++; + k++; + } + + /* Copy the remaining elements of R[], if there + are any */ + while (j < n2) + { + arr[k] = R[j]; + j++; + k++; + } +} + +/* l is for left index and r is right index of the + sub-array of arr to be sorted */ +void mergeSort(int arr[], int l, int r) +{ + if (l < r) + { + // Same as (l+r)/2, but avoids overflow for + // large l and h + int m = l+(r-l)/2; + + // Sort first and second halves + mergeSort(arr, l, m); + mergeSort(arr, m+1, r); + + merge(arr, l, m, r); + } +} + +/* UTILITY FUNCTIONS */ +/* Function to print an array */ +void printArray(int A[], int size) +{ + int i; + for (i=0; i < size; i++) + printf("%d ", A[i]); + printf("\n"); +} diff --git a/Sorting/Merge Sort/C/merge_sort.c b/Sorting/Merge Sort/C/merge_sort.c new file mode 100644 index 000000000..0de5b22a6 --- /dev/null +++ b/Sorting/Merge Sort/C/merge_sort.c @@ -0,0 +1,48 @@ +#include +void merge(int arr1[],int ll1,int ul1,int ll2,int ul2) +{ + int i=0,k,ll=ll1; + int arr3[100]; + while(ll1<=ul1&&ll2<=ul2) + { + if(arr1[ll1] [a] -> [a] +mergesort [] = [] +mergesort [x] = [x] +mergesort xs = let (a,b) = splitAt (div (length xs) 2) xs + in merge (mergesort a) (mergesort b) + +merge :: (Ord a) => [a] -> [a] -> [a] +merge xs [] = xs +merge [] ys = ys +merge (x:xs) (y:ys) + | (x <= y) = x:(merge xs (y:ys)) + |otherwise = y:(merge (x:xs) ys) + +main = do + let result = mergesort [5, 0, -3, 4, 1, 3, 1, -5, 0, 9, 1] + print result diff --git a/Sorting/MergeSort/java/merge_sort.java b/Sorting/Merge Sort/Java/merge_sort.java similarity index 100% rename from Sorting/MergeSort/java/merge_sort.java rename to Sorting/Merge Sort/Java/merge_sort.java diff --git a/Sorting/MergeSort/javascript/merge-sort.js b/Sorting/Merge Sort/Javascript/merge_sort.js similarity index 100% rename from Sorting/MergeSort/javascript/merge-sort.js rename to Sorting/Merge Sort/Javascript/merge_sort.js diff --git a/Sorting/MergeSort/python/mergesort.py b/Sorting/Merge Sort/Python/merge_sort.py similarity index 92% rename from Sorting/MergeSort/python/mergesort.py rename to Sorting/Merge Sort/Python/merge_sort.py index dcd9f2e58..cfaa3f73c 100644 --- a/Sorting/MergeSort/python/mergesort.py +++ b/Sorting/Merge Sort/Python/merge_sort.py @@ -1,45 +1,45 @@ -def Merge(left,right,A): - i=j=k=0 - - while(i < len(left) and j < len(right)): - if(left[i] < right[j]): - A[k]=left[i] - i+=1 - - else: - A[k]=right[j] - j+=1 - - k+=1 - - while(i < len(left)): - A[k]=left[i] - i+=1 - k+=1 - - while(j < len(right)): - A[k]=right[j] - j+=1 - k+=1 - - -def MergeSort(A): - left = [] - right = [] - n = len(A) - if(n<2): - return - mid = n/2 - for i in range(mid): - left.append(A[i]) - for i in range(mid,n): - right.append(A[i]) - - MergeSort(left) - MergeSort(right) - Merge(left,right,A) - - -A = [2,4,1,3,8,9,0,-2,-1] #given unsorted array -MergeSort(A) -print A +def Merge(left,right,A): + i=j=k=0 + + while(i < len(left) and j < len(right)): + if(left[i] < right[j]): + A[k]=left[i] + i+=1 + + else: + A[k]=right[j] + j+=1 + + k+=1 + + while(i < len(left)): + A[k]=left[i] + i+=1 + k+=1 + + while(j < len(right)): + A[k]=right[j] + j+=1 + k+=1 + + +def MergeSort(A): + left = [] + right = [] + n = len(A) + if(n<2): + return + mid = n/2 + for i in range(mid): + left.append(A[i]) + for i in range(mid,n): + right.append(A[i]) + + MergeSort(left) + MergeSort(right) + Merge(left,right,A) + + +A = [2,4,1,3,8,9,0,-2,-1] #given unsorted array +MergeSort(A) +print A diff --git a/Sorting/MergeSort/ruby/merge_sort.rb b/Sorting/Merge Sort/Ruby/merge_sort.rb similarity index 100% rename from Sorting/MergeSort/ruby/merge_sort.rb rename to Sorting/Merge Sort/Ruby/merge_sort.rb diff --git a/Sorting/Merge Sort/Rust/merge-sort.rs b/Sorting/Merge Sort/Rust/merge-sort.rs new file mode 100644 index 000000000..042367fed --- /dev/null +++ b/Sorting/Merge Sort/Rust/merge-sort.rs @@ -0,0 +1,55 @@ +fn merge(x1: &[T], x2: &[T], y: &mut [T]) { + assert_eq!(x1.len() + x2.len(), y.len()); + let mut i = 0; + let mut j = 0; + let mut k = 0; + while i < x1.len() && j < x2.len() { + if x1[i] < x2[j] { + y[k] = x1[i]; + k += 1; + i += 1; + } else { + y[k] = x2[j]; + k += 1; + j += 1; + } + } + if i < x1.len() { + y[k..].copy_from_slice(&x1[i..]); + } + if j < x2.len() { + y[k..].copy_from_slice(&x2[j..]); + } +} + +fn merge_sort(x: &mut [T]) { + let n = x.len(); + let m = n / 2; + + if n <= 1 { + return; + } + + merge_sort(&mut x[0..m]); + merge_sort(&mut x[m..n]); + + let mut y: Vec = x.to_vec(); + + merge(&x[0..m], &x[m..n], &mut y[..]); + + x.copy_from_slice(&y); +} + +fn main() { + println!("Sort numbers ascending"); + let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1]; + println!("Before: {:?}", numbers); + merge_sort(&mut numbers); + println!("After: {:?}\n", numbers); + + println!("Sort strings alphabetically"); + let mut strings = ["beach", "hotel", "airplane", "car", "house", "art"]; + println!("Before: {:?}", strings); + merge_sort(&mut strings); + println!("After: {:?}\n", strings); +} diff --git a/Sorting/MergeSort/Swift/mergeSort.swift b/Sorting/Merge Sort/Swift/merge_sort.swift similarity index 100% rename from Sorting/MergeSort/Swift/mergeSort.swift rename to Sorting/Merge Sort/Swift/merge_sort.swift diff --git a/Sorting/MergeSort/cpp/merge.cpp b/Sorting/MergeSort/cpp/merge.cpp deleted file mode 100644 index 919e95820..000000000 --- a/Sorting/MergeSort/cpp/merge.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/*Program for merge sort implementation in C++. */ - -#include -#include - -void mergeHalves(std::vector &A, int leftStart, int mid, int rightEnd) -{ - int n1=mid-leftStart+1, n2=rightEnd-mid; - std::vector left, right; - for (int i = 0; i < n1; i++) - { - left.push_back(A[leftStart+i]); - } - for (int i = 0; i < n2; i++) - { - right.push_back(A[mid+1+i]); - } - - int i=0, k=leftStart, j=0; - - while (i < n1 && j &A, int leftStart, int rightEnd) - -{/* - std::cout<<"Current list : \n"; - for(int i=0;i=rightEnd) - return; - - int mid = (leftStart+rightEnd)/2; - merge_sort(A,leftStart,mid); - merge_sort(A,mid+1,rightEnd); - - mergeHalves(A, leftStart, mid, rightEnd); -/* - std::cout<<"\nSorted list : \n"; - for(int i=0;i arr={10,2,23,-4,235,56,2,6,5,81,5,23,-4,346,-56,-54}; - - merge_sort(arr,0,arr.size()-1); - std::cout<<"\n\n\n"; - - for(int i=0;i arr[mi]) - mi = i; - return mi; - } - - // The main function that - // sorts given array using - // flip operations - static int pancakeSort(int arr[], int n) - { - // Start from the complete - // array and one by one - // reduce current size by one - for (int curr_size = n; curr_size > 1; --curr_size) - { - // Find index of the - // maximum element in - // arr[0..curr_size-1] - int mi = findMax(arr, curr_size); - - // Move the maximum element - // to end of current array - // if it's not already at - // the end - if (mi != curr_size-1) - { - // To move at the end, - // first move maximum - // number to beginning - flip(arr, mi); - - // Now move the maximum - // number to end by - // reversing current array - flip(arr, curr_size-1); - } - } - return 0; - } - - /* Utility function to print array arr[] */ - static void printArray(int arr[], int arr_size) - { - for (int i = 0; i < arr_size; i++) - System.out.print(arr[i] + " "); - System.out.println(""); - } - - /* Driver function to check for above functions*/ - public static void main (String[] args) - { - int arr[] = {23, 10, 20, 11, 12, 6, 7}; - int n = arr.length; - - pancakeSort(arr, n); - - System.out.println("Sorted Array: "); - printArray(arr, n); - } + +// Java program to +// sort array using +// pancake sort +import java.io.*; + +class PancakeSort { + + /* Reverses arr[0..i] */ + static void flip(int arr[], int i) + { + int temp, start = 0; + while (start < i) + { + temp = arr[start]; + arr[start] = arr[i]; + arr[i] = temp; + start++; + i--; + } + } + + // Returns index of the + // maximum element in + // arr[0..n-1] + static int findMax(int arr[], int n) + { + int mi, i; + for (mi = 0, i = 0; i < n; ++i) + if (arr[i] > arr[mi]) + mi = i; + return mi; + } + + // The main function that + // sorts given array using + // flip operations + static int pancakeSort(int arr[], int n) + { + // Start from the complete + // array and one by one + // reduce current size by one + for (int curr_size = n; curr_size > 1; --curr_size) + { + // Find index of the + // maximum element in + // arr[0..curr_size-1] + int mi = findMax(arr, curr_size); + + // Move the maximum element + // to end of current array + // if it's not already at + // the end + if (mi != curr_size-1) + { + // To move at the end, + // first move maximum + // number to beginning + flip(arr, mi); + + // Now move the maximum + // number to end by + // reversing current array + flip(arr, curr_size-1); + } + } + return 0; + } + + /* Utility function to print array arr[] */ + static void printArray(int arr[], int arr_size) + { + for (int i = 0; i < arr_size; i++) + System.out.print(arr[i] + " "); + System.out.println(""); + } + + /* Driver function to check for above functions*/ + public static void main (String[] args) + { + int arr[] = {23, 10, 20, 11, 12, 6, 7}; + int n = arr.length; + + pancakeSort(arr, n); + + System.out.println("Sorted Array: "); + printArray(arr, n); + } } \ No newline at end of file diff --git a/Sorting/Pancake Sorting/Python3/pancake.py b/Sorting/Pancake Sorting/Python3/pancake.py new file mode 100644 index 000000000..5e39c4a88 --- /dev/null +++ b/Sorting/Pancake Sorting/Python3/pancake.py @@ -0,0 +1,27 @@ +tutor = False + + +def pancakesort(array): + if len(array) <= 1: + return array + if tutor: + print() + for size in range(len(array), 1, -1): + maxindex = max(range(size), key=lamdba i: array[i]) + if maxindex+1 != size: + if maxindex != 0: + if tutor: + print( + 'With: %r doflip %i' % ( + ' '.join(str(x) for x in array), maxindex+1) + ) + array[:maxindex+1] = reversed(array[:maxindex+1]) + if tutor: + print( + 'With: %r doflip %i' % ( + ' '.join(str(x) for x in array), size + ) + ) + array[:size] = reversed(array[:size]) + if tutor: + print() diff --git a/Sorting/Pancake Sorting/Ruby/pancakeSort.rb b/Sorting/Pancake Sorting/Ruby/pancakeSort.rb new file mode 100644 index 000000000..ec48f22da --- /dev/null +++ b/Sorting/Pancake Sorting/Ruby/pancakeSort.rb @@ -0,0 +1,22 @@ +class Array + def pancake_sort! + num_flips = 0 + (self.size-1).downto(1) do |end_idx| + max = self[0..end_idx].max + max_idx = self[0..end_idx].index(max) + next if max_idx == end_idx + + if max_idx > 0 + self[0..max_idx] = self[0..max_idx].reverse + p [num_flips += 1, self] if $DEBUG + end + + self[0..end_idx] = self[0..end_idx].reverse + p [num_flips += 1, self] if $DEBUG + end + self + end + end + + p a = (1..9).to_a.shuffle + p a.pancake_sort! diff --git a/Sorting/Patience Sorting/C++/patience_sorting.cpp b/Sorting/Patience Sorting/C++/patience_sorting.cpp new file mode 100644 index 000000000..0d3364cf3 --- /dev/null +++ b/Sorting/Patience Sorting/C++/patience_sorting.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include + +template +struct pile_less { + bool operator()(const std::stack &pile1, const std::stack &pile2) const { + return pile1.top() < pile2.top(); + } +}; + +template +struct pile_greater { + bool operator()(const std::stack &pile1, const std::stack &pile2) const { + return pile1.top() > pile2.top(); + } +}; + + +template +void patience_sort(Iterator first, Iterator last) { + typedef typename std::iterator_traits::value_type E; + typedef std::stack Pile; + + std::vector piles; + // sort into piles + for (Iterator it = first; it != last; it++) { + E& x = *it; + Pile newPile; + newPile.push(x); + typename std::vector::iterator i = + std::lower_bound(piles.begin(), piles.end(), newPile, pile_less()); + if (i != piles.end()) + i->push(x); + else + piles.push_back(newPile); + } + + // priority queue allows us to merge piles efficiently + // we use greater-than comparator for min-heap + std::make_heap(piles.begin(), piles.end(), pile_greater()); + for (Iterator it = first; it != last; it++) { + std::pop_heap(piles.begin(), piles.end(), pile_greater()); + Pile &smallPile = piles.back(); + *it = smallPile.top(); + smallPile.pop(); + if (smallPile.empty()) + piles.pop_back(); + else + std::push_heap(piles.begin(), piles.end(), pile_greater()); + } + assert(piles.empty()); +} + +int main() { + int a[] = {4, 65, 2, -31, 0, 99, 83, 782, 1}; + patience_sort(a, a+sizeof(a)/sizeof(*a)); + std::copy(a, a+sizeof(a)/sizeof(*a), std::ostream_iterator(std::cout, ", ")); + std::cout << std::endl; + return 0; +} \ No newline at end of file diff --git a/Sorting/Patience Sorting/Java/patience_sorting.java b/Sorting/Patience Sorting/Java/patience_sorting.java new file mode 100644 index 000000000..49a5e57ff --- /dev/null +++ b/Sorting/Patience Sorting/Java/patience_sorting.java @@ -0,0 +1,38 @@ +import java.util.*; + +public class PatienceSort { + public static > void sort (E[] n) { + List> piles = new ArrayList>(); + // sort into piles + for (E x : n) { + Pile newPile = new Pile(); + newPile.push(x); + int i = Collections.binarySearch(piles, newPile); + if (i < 0) i = ~i; + if (i != piles.size()) + piles.get(i).push(x); + else + piles.add(newPile); + } + + // priority queue allows us to retrieve least pile efficiently + PriorityQueue> heap = new PriorityQueue>(piles); + for (int c = 0; c < n.length; c++) { + Pile smallPile = heap.poll(); + n[c] = smallPile.pop(); + if (!smallPile.isEmpty()) + heap.offer(smallPile); + } + assert(heap.isEmpty()); + } + + private static class Pile> extends Stack implements Comparable> { + public int compareTo(Pile y) { return peek().compareTo(y.peek()); } + } + + public static void main(String[] args) { + Integer[] a = {4, 65, 2, -31, 0, 99, 83, 782, 1}; + sort(a); + System.out.println(Arrays.toString(a)); + } +} \ No newline at end of file diff --git a/Sorting/Patience Sorting/Python3/patience_sort.py b/Sorting/Patience Sorting/Python3/patience_sort.py new file mode 100644 index 000000000..44441470a --- /dev/null +++ b/Sorting/Patience Sorting/Python3/patience_sort.py @@ -0,0 +1,26 @@ +from bisect import bisect_left +from heapq import merge + + +class Pile(list): + def __lt__(self, num): return self[-1] < num[-1] + + def __eq__(self, num): return self[-1] == num[-1] + + +def patience_sort(array): + piles = [] + for elem in array: + curr = Pile([elem]) + i = bisect_left(piles, curr) + if i != len(piles): + piles[i].append(elem) + else: + piles.append(curr) + + return list(merge(*[reversed(pile) for pile in piles])) + + +if __name__ == "__main__": + a = [4, 65, 2, -31, 0, 99, 83, 782, 1] + print(patience_sort(a)) diff --git a/Sorting/README.md b/Sorting/README.md new file mode 100644 index 000000000..373e2f0b7 --- /dev/null +++ b/Sorting/README.md @@ -0,0 +1,16 @@ +## Sorting Algorithms + + +| Sorting Algorithm | C | CPP | Java | Python | JavaScript | C# | Golang | Ruby | Rust | Swift | +|:--------------|:----------------:|:----------------:|:----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:|:-----------------:| +| [Bogo Sort](https://en.wikipedia.org/wiki/Bogosort) | [:heavy_check_mark:](Bogosort/C/bogosort.c) | [:heavy_check_mark:](Bogosort/C%2B%2B/Bogosort.cpp) | [:heavy_check_mark:](Bogosort/Java/Bogosort.java) | [:heavy_check_mark:](Bogosort/Python/bogosort.py) | | [:heavy_check_mark:](Bogosort/C%20Sharp/Bogosort.cs) | | [:heavy_check_mark:](Bogosort/Ruby/bogosort.rb) | | | +| [Bubble Sort](https://en.wikipedia.org/wiki/Bubble_sort) | [:heavy_check_mark:](Bubble%20Sort/C/bubble_sort.c) | [:heavy_check_mark:](Bubble%20Sort/CPP/bubble_sort.cpp) | [:heavy_check_mark:](Bubble%20Sort/Java/BubbleSort.java) | [:heavy_check_mark:](Bubble%20Sort/Python/bubble_sort.py) | [:heavy_check_mark:](Bubble%20Sort/Javascript/bubble_sort.js) | [:heavy_check_mark:](Bubble%20Sort/C%20Sharp/BubbleSort.cs) | [:heavy_check_mark:](Bubble%20Sort/Go/bubble_sort.go) | [:heavy_check_mark:](Bubble%20Sort/Ruby/bubble_sort.rb) | [:heavy_check_mark:](Bubble%20Sort/Rust/bubble_sort.rs) | [:heavy_check_mark:](Bubble%20Sort/Swift/bubble_sort.swift) | +|[Bucket Sort](https://en.wikipedia.org/wiki/Bucket_sort) | | [:heavy_check_mark:](Bucket%20Sort/C%2B%2B/bucket_sort.cpp) | [:heavy_check_mark:](Bucket%20Sort/Java/bucket_sort.java) | | [:heavy_check_mark:](Bucket%20Sort/Javascript/bucket_sort.js) | | | | | | +| [Counting Sort](https://en.wikipedia.org/wiki/Counting_sort) | [:heavy_check_mark:](Counting%20Sort/C/Counting_sort.c) | [:heavy_check_mark:](Counting%20Sort/CPP/counting_sort.cpp) | [:heavy_check_mark:](Counting%20Sort/Java/counting_sort.java) | [:heavy_check_mark:](Counting%20Sort/Python/counting_sort.py) | [:heavy_check_mark:](Counting%20Sort/Javascript/counting_sort.js) | | [:heavy_check_mark:](Counting%20Sort/Golang/count-sort.go) | [:heavy_check_mark:](Counting%20Sort/Ruby/countSort.rb) | [:heavy_check_mark:](Counting%20Sort/Rust/counting-sort.rs)| | +| [Heap Sort](https://en.wikipedia.org/wiki/Heapsort) | [:heavy_check_mark:](Heapsort/C/Heapsort.c) | [:heavy_check_mark:](Heapsort/C%2B%2B/heapsort.cpp) | [:heavy_check_mark:](Heapsort/Java/HeapSort.java) | [:heavy_check_mark:](Heapsort/Python/heapsort.py) | [:heavy_check_mark:](Heapsort/Javascript/heapsort.js) | [:heavy_check_mark:](Heapsort/C%20Sharp/heapsort.cs) | | [:heavy_check_mark:](Heapsort/Ruby/heapsort.rb) | | | +| [Insertion Sort](https://en.wikipedia.org/wiki/Insertion_sort) | [:heavy_check_mark:](Insertion%20Sort/C/insertion_sort.c) | [:heavy_check_mark:](Insertion%20Sort/C%2B%2B/insertion_sort.cpp) | [:heavy_check_mark:](Insertion%20Sort/Java/insertion_sort.java) | [:heavy_check_mark:](Insertion%20Sort/Python/insertion_sort.py) | [:heavy_check_mark:](Insertion%20Sort/Javascript/insertion_sort.js) | | [:heavy_check_mark:](Insertion%20Sort/Go/insertion_sort.go) | [:heavy_check_mark:](Insertion%20Sort/Ruby/insertion_sort.rb) | [:heavy_check_mark:](Insertion%20Sort/Rust/insertion_sort.rs) | | +| [Merge Sort](https://en.wikipedia.org/wiki/Merge_sort) | [:heavy_check_mark:](Merge%20Sort/C/merge_sort.c) | [:heavy_check_mark:](Merge%20Sort/C%2B%2B/merge_sort.cpp) | [:heavy_check_mark:](Merge%20Sort/Java/merge_sort.java) | [:heavy_check_mark:](Merge%20Sort/Python/merge_sort.py) | [:heavy_check_mark:](Merge%20Sort/Javascript/merge_sort.js) | | | [:heavy_check_mark:](Merge%20Sort/Ruby/merge_sort.rb) | [:heavy_check_mark:](Merge%20Sort/Rust/merge-sort.rs) | [:heavy_check_mark:](Merge%20Sort/Swift/merge_sort.swift) | +| [Quick Sort](https://en.wikipedia.org/wiki/Quick_sort) | [:heavy_check_mark:](quickSort/C/quick_sort.c) | [:heavy_check_mark:](quickSort/C%2B%2B/quick_sort.cpp) | [:heavy_check_mark:](quickSort/Java/quick_sort.java) | [:heavy_check_mark:](quickSort/python/quick_sort.py) | [:heavy_check_mark:](quickSort/Javascript/quick_sort.js) | [:heavy_check_mark:](quickSort/csharp/QuickSort.cs) | [:heavy_check_mark:](quickSort/Go/quick_sort.go) | [:heavy_check_mark:](quickSort/Ruby/quick_sort.rb) | [:heavy_check_mark:](quickSort/Rust/quick-sort.rs) | | +| [Radix Sort](https://en.wikipedia.org/wiki/Radix_sort) | | [:heavy_check_mark:](Radix%20Sort/C%2B%2B/radix_sort.cpp) | [:heavy_check_mark:](Radix%20Sort/Java/radix_sort.java) | [:heavy_check_mark:](Radix%20Sort/python/Radix_Sort.py) | | | [:heavy_check_mark:](Radix%20Sort/Go/radix_sort.go) | [:heavy_check_mark:](Radix%20Sort/Ruby/radixSort.rb) | | | +| [Selection Sort](https://en.wikipedia.org/wiki/Selection_sort) | [:heavy_check_mark:](Selection%20Sort/C/selection_sort.c) | [:heavy_check_mark:](Selection%20Sort/C%2B%2B/selection_sort.cpp) | [:heavy_check_mark:](Selection%20Sort/Java/selection_sort.java) | [:heavy_check_mark:](Selection%20Sort/Python/selection_sort.py) | [:heavy_check_mark:](Selection%20Sort/JavaScript/selectionSort.js) | | [:heavy_check_mark:](Selection%20Sort/Go/selection_sort.go) | [:heavy_check_mark:](Selection%20Sort/Ruby/selSort.rb) | [:heavy_check_mark:](Selection%20Sort/Rust/selection_sort.rs) | | +| [Shell Sort](https://en.wikipedia.org/wiki/Shellsort) | [:heavy_check_mark:](ShellSort/c/shell_sort.c) | [:heavy_check_mark:](ShellSort/C%2B%2B/shell_sort.cpp) | [:heavy_check_mark:](ShellSort/Java/ShellSort.java) | [:heavy_check_mark:](ShellSort/python/shell_sort.py) | [:heavy_check_mark:](ShellSort/Javascript/shellsort.js) | [:heavy_check_mark:](ShellSort/csharp/ShellSort.cs) | | [:heavy_check_mark:](ShellSort/Ruby/shellSort.rb) | | | diff --git a/Sorting/Radix Sort/cpp/RadixSort.cpp b/Sorting/Radix Sort/C++/radix_sort.cpp similarity index 100% rename from Sorting/Radix Sort/cpp/RadixSort.cpp rename to Sorting/Radix Sort/C++/radix_sort.cpp diff --git a/Sorting/Radix Sort/golang/radixsort.go b/Sorting/Radix Sort/Go/radix_sort.go similarity index 100% rename from Sorting/Radix Sort/golang/radixsort.go rename to Sorting/Radix Sort/Go/radix_sort.go diff --git a/Sorting/Radix Sort/java/RadixSort.java b/Sorting/Radix Sort/Java/radix_sort.java old mode 100755 new mode 100644 similarity index 100% rename from Sorting/Radix Sort/java/RadixSort.java rename to Sorting/Radix Sort/Java/radix_sort.java diff --git a/Sorting/Radix Sort/Ruby/radixSort.rb b/Sorting/Radix Sort/Ruby/radixSort.rb new file mode 100644 index 000000000..7716eb9b3 --- /dev/null +++ b/Sorting/Radix Sort/Ruby/radixSort.rb @@ -0,0 +1,23 @@ +class Array + def radix_sort(base=10) + ary = dup + rounds = (Math.log(ary.minmax.map(&:abs).max)/Math.log(base)).floor + 1 + rounds.times do |i| + buckets = Array.new(2*base){[]} + base_i = base**i + ary.each do |n| + digit = (n/base_i) % base + digit += base if 0<=n + buckets[digit] << n + end + ary = buckets.flatten + p [i, ary] if $DEBUG + end + ary + end + def radix_sort!(base=10) + replace radix_sort(base) + end +end + +p [170, 45, 75, 90, 2, 24, 802, 66].radix_sort diff --git a/Sorting/Radix Sort/python/Radix_Sort.py b/Sorting/Radix Sort/python/Radix_Sort.py new file mode 100644 index 000000000..6b6825cef --- /dev/null +++ b/Sorting/Radix Sort/python/Radix_Sort.py @@ -0,0 +1,46 @@ +import time + +# Function that takes a list and sorts using radix sort implementation +def radixsort(toBeSorted): + + digit = 1 + atTheEnd = False + r = 10 # The base of the numbers we choose to sort + + while not atTheEnd: + # Only remains true if we are calculating for the highest significant digit. + atTheEnd = True + + # Initialize the bins which are a series of lists + bins = [list() for _ in range(r)] + + # Place items inside toBeSorted buffer into their respective bins + for i in toBeSorted: + temp = i / digit + bins[temp % r].append(i) + if temp > 0: + atTheEnd = False + + # Put the items in the bins back into the toBeSorted buffer + toBeSortedIndex = 0 + for i in range(r): # Goes through each bin + bin = bins[i] + for j in bin: # Goes through each element in a given bin + toBeSorted[toBeSortedIndex] = j + toBeSortedIndex = toBeSortedIndex + 1 + + # Increment to sort by the next digit + digit = digit * r + +A = [201, 12, 1323, 32, 58, 91, 2, 1, 13, 13314, 21230, 1000, 1200] +print "Unsorted list: " +print A + +start = time.time() +radixsort(A) +end = time.time() + +print "Sorted list: " +print A +print "Time Taken: " +print str(end - start) + "ms" diff --git a/Sorting/RankSort/cpp/RankSort.cpp b/Sorting/Rank Sort/C++/rank_sort.cpp similarity index 100% rename from Sorting/RankSort/cpp/RankSort.cpp rename to Sorting/Rank Sort/C++/rank_sort.cpp diff --git a/Sorting/Recursive Bubble Sort/python/recBubble.py b/Sorting/Recursive Bubble Sort/python/recBubble.py deleted file mode 100644 index 95b5846ba..000000000 --- a/Sorting/Recursive Bubble Sort/python/recBubble.py +++ /dev/null @@ -1,25 +0,0 @@ - -# Author Shubham Bindal - -def bubble_sort(list_): - for i, num in enumerate(list_): - try: - if list_[i+1] < num: - list_[i] = list_[i+1] - list_[i+1] = num - bubble_sort(list_) - except IndexError: - pass - return list_ - -list_=list(map(int,input("Enter the numbers to be sorted\n").split())) - -bubble_sort(list_) - -print("Sorted array:"); - -for i in range(0, len(list_)): - - print(list_[i], end=' ') - - diff --git a/Sorting/Selection Sort/C++/selection_sort.cpp b/Sorting/Selection Sort/C++/selection_sort.cpp new file mode 100644 index 000000000..f18ceee6d --- /dev/null +++ b/Sorting/Selection Sort/C++/selection_sort.cpp @@ -0,0 +1,33 @@ +#include +#include +void main() +{ + clrscr(); + int size, arr[50], i, j, temp,pos; + cout<<"Enter Array Size : "; + cin>>size; + cout<<"Enter Array Elements : "; + for(i = 0; i < size; i++) + { + cin>>arr[i]; + } + cout<<"Sorting array using selection sort...\n"; + for(i = 0; i < size; i++) + { + pos = i; + for(j = i + 1 ; j < size ; j++) + { + if(arr[j] < arr[pos]) + pos = j; + } + temp = arr[i]; + arr[i] = arr[pos]; + arr[pos] = temp; + } + cout<<"Now the Array after sorting is :\n"; + for(i = 0; i < size; i++) + { + cout< { + for (let i = 0; i < arr.length - 1; i += 1) { + let iMin = i; + for (let j = i + 1; j < arr.length; j += 1) { + if (arr[iMin] > arr[j]) { + iMin = j; + } + } + if (iMin !== i) { + [arr[iMin], arr[i]] = [arr[i], arr[iMin]]; + } + } +}; \ No newline at end of file diff --git a/Sorting/Selection Sort/python/SelectionSort.py b/Sorting/Selection Sort/Python/selection_sort.py similarity index 100% rename from Sorting/Selection Sort/python/SelectionSort.py rename to Sorting/Selection Sort/Python/selection_sort.py diff --git a/Sorting/Selection Sort/Ruby/selSort.rb b/Sorting/Selection Sort/Ruby/selSort.rb new file mode 100644 index 000000000..2edfe58cb --- /dev/null +++ b/Sorting/Selection Sort/Ruby/selSort.rb @@ -0,0 +1,19 @@ +def selection_sort(a, n) + (0..n - 2).each do |i| + i_min = i + (i + 1..n - 1).each do |j| + if a[j] < a[i_min] + i_min = j + end + end + + temp = a[i] + a[i] = a[i_min] + a[i_min] = temp + #byebug + end + a + end + + a = [2,7,4,1,5,3] + selection_sort(a, a.size) diff --git a/Sorting/Selection Sort/Rust/selection_sort.rs b/Sorting/Selection Sort/Rust/selection_sort.rs new file mode 100644 index 000000000..744af9e87 --- /dev/null +++ b/Sorting/Selection Sort/Rust/selection_sort.rs @@ -0,0 +1,14 @@ +pub fn selection_sort(array: &mut [T]) { + let len = array.len(); + for i in 0..len { + let min = (i..len).min_by_key(|x| array[*x]) + .unwrap(); + array.swap(min, i); + } +} + +pub fn main() { + let mut array: [i32; 9] = [2,3,7,5,3,8,12,54,21]; + selection_sort(&mut array); + assert_eq!(array, [2,3,3,5,7,8,12,21,54]); +} diff --git a/Sorting/Selection Sort/cpp/selectionsort.cpp b/Sorting/Selection Sort/cpp/selectionsort.cpp deleted file mode 100644 index 9dab7005b..000000000 --- a/Sorting/Selection Sort/cpp/selectionsort.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -void main() -{ - clrscr(); - int size, arr[50], i, j, temp; - cout<<"Enter Array Size : "; - cin>>size; - cout<<"Enter Array Elements : "; - for(i=0; i>arr[i]; - } - cout<<"Sorting array using selection sort...\n"; - for(i=0; iarr[j]) - { - temp=arr[i]; - arr[i]=arr[j]; - arr[j]=temp; - } - } - } - cout<<"Now the Array after sorting is :\n"; - for(i=0; i 0; gap /= 2) + { + // Do a gapped insertion sort for this gap size. + // The first gap elements a[0..gap-1] are already + // in gapped order keep adding one more element + // until the entire array is gap sorted + for (int i = gap; i < n; i += 1) + { + // add a[i] to the elements that have been gap + // sorted save a[i] in temp and make a hole at + // position i + int temp = arr[i]; + + // shift earlier gap-sorted elements up until + // the correct location for a[i] is found + int j; + for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) + arr[j] = arr[j - gap]; + + // put temp (the original a[i]) in its correct + // location + arr[j] = temp; + } + } + return 0; + } diff --git a/Sorting/ShellSort/Javascript/shellsort.js b/Sorting/ShellSort/Javascript/shellsort.js new file mode 100644 index 000000000..0dd8ed5ba --- /dev/null +++ b/Sorting/ShellSort/Javascript/shellsort.js @@ -0,0 +1,25 @@ +function shellSort(arr) { + var increment = arr.length / 2; + while (increment > 0) { + for (i = increment; i < arr.length; i++) { + var j = i; + var temp = arr[i]; + + while (j >= increment && arr[j-increment] > temp) { + arr[j] = arr[j-increment]; + j = j - increment; + } + + arr[j] = temp; + } + + if (increment == 2) { + increment = 1; + } else { + increment = parseInt(increment*5 / 11); + } + } + return arr; +} + +console.log(shellSort([5, 0, 1, 3, -1, 4, 2])); \ No newline at end of file diff --git a/Sorting/ShellSort/Ruby/shellSort.rb b/Sorting/ShellSort/Ruby/shellSort.rb new file mode 100644 index 000000000..f98271e9f --- /dev/null +++ b/Sorting/ShellSort/Ruby/shellSort.rb @@ -0,0 +1,20 @@ +class Array + def shellsort! + inc = length / 2 + while inc != 0 + inc.step(length-1) do |i| + el = self[i] + while i >= inc and self[i - inc] > el + self[i] = self[i - inc] + i -= inc + end + self[i] = el + end + inc = (inc == 2 ? 1 : (inc * 5.0 / 11).to_i) + end + self + end + end + + data = [22, 7, 2, -5, 8, 4] + data.shellsort! diff --git a/Sorting/ShellSort/csharp/ShellSort.cs b/Sorting/ShellSort/csharp/ShellSort.cs new file mode 100644 index 000000000..663e1c0ea --- /dev/null +++ b/Sorting/ShellSort/csharp/ShellSort.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; + +namespace Shell_Sort +{ + public class SortShell + { + static void Main(string[] args) + { + int[] arr = new int[] { 5, -4, 11, 0, 18, 22, 67, 51, 6 }; + int n; + + n = arr.Length; + Console.WriteLine("Original Array Elements :"); + show_array_elements(arr); + shellSort(arr, n); + Console.WriteLine("\nSorted Array Elements :"); + show_array_elements(arr); + } + + static void shellSort(int[] arr, int array_size) + { + int i, j, inc, temp; + inc = 3; + while (inc > 0) + { + for (i = 0; i < array_size; i++) + { + j = i; + temp = arr[i]; + while ((j >= inc) && (arr[j - inc] > temp)) + { + arr[j] = arr[j - inc]; + j = j - inc; + } + arr[j] = temp; + } + if (inc / 2 != 0) + inc = inc / 2; + else if (inc == 1) + inc = 0; + else + inc = 1; + } + } + + static void show_array_elements(int[] arr) + { + foreach (var element in arr) + { + Console.Write(element + " "); + } + Console.Write("\n"); + + } + } +} \ No newline at end of file diff --git a/Sorting/SlowSort/python/SlowSort.py b/Sorting/SlowSort/python/SlowSort.py new file mode 100644 index 000000000..04ffedac9 --- /dev/null +++ b/Sorting/SlowSort/python/SlowSort.py @@ -0,0 +1,25 @@ +# SlowSort is an example of MultiplyAndSurrender - a worst possible sort algorithm: +# For more information see http://wiki.c2.com/?SlowSort + + +# This procedure sorts the subarray A[i]...A[j] +def SlowSort(A, i, j): + if i >= j: + return + m = ((i + j) // 2) + SlowSort(A, i, m) + SlowSort(A, m + 1, j) + if A[m] > A[j]: + A[m], A[j] = A[j], A[m] + SlowSort(A, i, j - 1) + return A + + +# Example run of SlowSort +def main(): + arr = [2, 7, 9, 3, 1, 6, 5, 4, 12] + print("Result: " + str(SlowSort(arr, 0, len(arr) - 1))) + + +if __name__ == "__main__": + main() diff --git a/Sorting/timSort/c/tim-sort.c b/Sorting/Timsort/C/timsort.c similarity index 100% rename from Sorting/timSort/c/tim-sort.c rename to Sorting/Timsort/C/timsort.c diff --git a/Sorting/Timsort/Python/TimSort.py b/Sorting/Timsort/Python/TimSort.py new file mode 100644 index 000000000..ce80f41a3 --- /dev/null +++ b/Sorting/Timsort/Python/TimSort.py @@ -0,0 +1,85 @@ +# based off of this code https://gist.github.com/nandajavarma/a3a6b62f34e74ec4c31674934327bbd3 +# Brandon Skerritt +# https://skerritt.tech + +def binary_search(the_array, item, start, end): + if start == end: + if the_array[start] > item: + return start + else: + return start + 1 + if start > end: + return start + + mid = round((start + end)/ 2) + + if the_array[mid] < item: + return binary_search(the_array, item, mid + 1, end) + + elif the_array[mid] > item: + return binary_search(the_array, item, start, mid - 1) + + else: + return mid + +""" +Insertion sort that timsort uses if the array size is small or if +the size of the "run" is small +""" +def insertion_sort(the_array): + l = len(the_array) + for index in range(1, l): + value = the_array[index] + pos = binary_search(the_array, value, 0, index - 1) + the_array = the_array[:pos] + [value] + the_array[pos:index] + the_array[index+1:] + return the_array + +def merge(left, right): + """Takes two sorted lists and returns a single sorted list by comparing the + elements one at a time. + [1, 2, 3, 4, 5, 6] + """ + if not left: + return right + if not right: + return left + if left[0] < right[0]: + return [left[0]] + merge(left[1:], right) + return [right[0]] + merge(left, right[1:]) + +def timsort(the_array): + runs, sorted_runs = [], [] + length = len(the_array) + new_run = [the_array[0]] + + # for every i in the range of 1 to length of array + for i in range(1, length): + # if i is at the end of the list + if i == length - 1: + new_run.append(the_array[i]) + runs.append(new_run) + break + # if the i'th element of the array is less than the one before it + if the_array[i] < the_array[i-1]: + # if new_run is set to None (NULL) + if not new_run: + runs.append([the_array[i]]) + new_run.append(the_array[i]) + else: + runs.append(new_run) + new_run = [] + # else if its equal to or more than + else: + new_run.append(the_array[i]) + + # for every item in runs, append it using insertion sort + for item in runs: + sorted_runs.append(insertion_sort(item)) + + # for every run in sorted_runs, merge them + sorted_array = [] + for run in sorted_runs: + sorted_array = merge(sorted_array, run) + + print(sorted_array) +timsort([2, 3, 1, 5, 6, 7]) \ No newline at end of file diff --git a/Sorting/Topological Sort/C/topological_sort.c b/Sorting/Topological Sorting/C/topological_sorting.c similarity index 100% rename from Sorting/Topological Sort/C/topological_sort.c rename to Sorting/Topological Sorting/C/topological_sorting.c diff --git a/Sorting/bubbleSort/D/bubble_sort.d b/Sorting/bubbleSort/D/bubble_sort.d new file mode 100644 index 000000000..c401c7809 --- /dev/null +++ b/Sorting/bubbleSort/D/bubble_sort.d @@ -0,0 +1,27 @@ +/* I am trying to implement the bubbleSort algorithm using the +basic approach , variables are used in a way to enhace readability*/ + +import std.stdio, std.algorithm : swap; + +T[] bubbleSort(T)(T[] data) pure nothrow +{ + foreach_reverse (n; 0 .. data.length) + { + bool swapped; + foreach (i; 0 .. n) + if (data[i] > data[i + 1]) { + swap(data[i], data[i + 1]); + swapped = true; + } + if (!swapped) + break; + } + return data; +} + + +void main() +{ + auto array = [28, 44, 46, 24, 19, 2, 17, 11, 25, 4]; + writeln(array.bubbleSort()); +} diff --git a/Sorting/bubbleSort/cpp/bubble_sort.cpp b/Sorting/bubbleSort/cpp/bubble_sort.cpp deleted file mode 100644 index 0f27e42f1..000000000 --- a/Sorting/bubbleSort/cpp/bubble_sort.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* Bubble Sort implementation in C++ - * Author : Manvi Gupta - * Input : array length and elements - * Output : Sorted array elements - */ -#include -using namespace std; - -int n; - -void bubble_Sort(int a[]) - { - - for(int i=0; i a[j+1]) - { - swap(a[j+1], a[j]); - } - } - - int main() - { - cin >> n; - int a[n]; - for(int i=0; i> a[i]; - bubble_Sort(a); - for (int i = 0; i < n; i++) { - std::cout << a[i] << '\n'; - } - return 0; - } diff --git a/Sorting/bubbleSort/golang/bubbleSort.go b/Sorting/bubbleSort/golang/bubbleSort.go deleted file mode 100644 index d259c896c..000000000 --- a/Sorting/bubbleSort/golang/bubbleSort.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "fmt" -) - -var toBeSorted [10]int = [10]int{1,3,2,4,8,6,7,2,3,0} - -func bubbleSort(input [10]int) { - // n is the number of items in our list - n := 10 - swapped := true - for swapped { - swapped = false - for i := 1; i < n-1; i++ { - if input[i-1] > input[i] { - fmt.Println("Swapping") - // swap values using Go's tuple assignment - input[i], input[i-1] = input[i-1], input[i] - swapped = true - } - } - } - fmt.Println(input) -} - - -func main() { - fmt.Println("Hello World") - bubbleSort(toBeSorted) - -} \ No newline at end of file diff --git a/Sorting/bubbleSort/lua/bubblesort.lua b/Sorting/bubbleSort/lua/bubblesort.lua new file mode 100644 index 000000000..2f0878b01 --- /dev/null +++ b/Sorting/bubbleSort/lua/bubblesort.lua @@ -0,0 +1,23 @@ +-- Bubble sort (also known as sinking sort) is a simple sorting algorithm that +-- repeatedly steps through the list to be sorted, compares each pair of +-- adjacent items and swaps them if they are in the wrong order. The pass +-- through the list is repeated until no swaps are needed, which indicates that +-- the list is sorted. + +local function bubblesort(t) + repeat + local sorted = true + for i=2, #t do + if (t[i-1] > t[i]) then + t[i-1], t[i] = t[i], t[i-1] + sorted = false + end + end + until sorted +end + +local numbers = {5, 1, 4, 2, 8} +bubblesort(numbers) +for _, number in ipairs(numbers) do + print(number) +end diff --git a/Sorting/countsort/C/counting sort.c b/Sorting/countsort/C/counting sort.c deleted file mode 100644 index 0c58f73f7..000000000 --- a/Sorting/countsort/C/counting sort.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#define RANGE 255 - -// The main function that sort the given string arr[] in -// alphabatical order -void countSort(char arr[]) -{ - // The output character array that will have sorted arr - char output[strlen(arr)]; - - // Create a count array to store count of inidividul - // characters and initialize count array as 0 - int count[RANGE + 1], i; - memset(count, 0, sizeof(count)); - - // Store count of each character - for(i = 0; arr[i]; ++i) - ++count[arr[i]]; - - // Change count[i] so that count[i] now contains actual - // position of this character in output array - for (i = 1; i <= RANGE; ++i) - count[i] += count[i-1]; - - // Build the output character array - for (i = 0; arr[i]; ++i) - { - output[count[arr[i]]-1] = arr[i]; - --count[arr[i]]; - } - - // Copy the output array to arr, so that arr now - // contains sorted characters - for (i = 0; arr[i]; ++i) - arr[i] = output[i]; -} - -// Driver program to test above function -int main() -{ - char arr[] = "Hi there!";//"applepp"; - - countSort(arr); - - printf("Sorted character array is %sn", arr); - return 0; -} diff --git a/Sorting/pigeonhole/pigeonhole_sorting.py b/Sorting/pigeonhole/pigeonhole_sorting.py new file mode 100644 index 000000000..4990b28c8 --- /dev/null +++ b/Sorting/pigeonhole/pigeonhole_sorting.py @@ -0,0 +1,40 @@ +# Python program to implement Pigeonhole Sorting in python + +#Algorithm for the pigeonhole sorting + +def pigeonhole_sort(a): + # size of range of values in the list (ie, number of pigeonholes we need) + + min_val = min(a) # min()finds the minimum value + max_val = max(a) # max() finds the maximum value + + size = max_val - min_val + 1 # size is difference of max and min values plus one + + # list of pigeonholes of size equal to the variable size + holes = [0] * size + + # Populate the pigeonholes. + for x in a: + assert type(x) is int, "integers only please" + holes[x - min_val] += 1 + + # Putting the elements back into the array in an order. + i = 0 + for count in range(size): + while holes[count] > 0: + holes[count] -= 1 + a[i] = count + min_val + i += 1 + +def main(): + + a = [8, 3, 2, 7, 4, 6, 8] + print("Sorted order is : ", end = ' ') + + pigeonhole_sort(a) + + for i in range(0, len(a)): + print(a[i], end = ' ') + +if __name__ == '__main__': + main() diff --git a/Sorting/pigeonholesort.cpp b/Sorting/pigeonholesort.cpp new file mode 100644 index 000000000..39ab7b116 --- /dev/null +++ b/Sorting/pigeonholesort.cpp @@ -0,0 +1,57 @@ +//Pigeonhole sorting is a sorting algorithm that is suitable for sorting lists of elements where the number of elements +//and the number of possible key values are approximately the same.It requires O(n + Range) time where n is number of elements +//in input array and ‘Range’ is number of possible values in array. + +#include +using namespace std; + +/* Sorts the array using pigeonhole algorithm */ +void pigeonholeSort(int arr[], int n) +{ + // Find minimum and maximum values in arr[] + int min = arr[0], max = arr[0]; + for (int i = 1; i < n; i++) + { + if (arr[i] < min) + min = arr[i]; + if (arr[i] > max) + max = arr[i]; + } + int range = max - min + 1; // Find range + + // Create an array of vectors. Size of array + // range. Each vector represents a hole that + // is going to contain matching elements. + vector holes[range]; + + // Traverse through input array and put every + // element in its respective hole + for (int i = 0; i < n; i++) + holes[arr[i]-min].push_back(arr[i]); + + // Traverse through all holes one by one. For + // every hole, take its elements and put in + // array. + int index = 0; // index in sorted array + for (int i = 0; i < range; i++) + { + vector::iterator it; + for (it = holes[i].begin(); it != holes[i].end(); ++it) + arr[index++] = *it; + } +} + +// Driver program to test the above function +int main() +{ + int arr[] = {8, 3, 2, 7, 4, 6, 8}; + int n = sizeof(arr)/sizeof(arr[0]); + + pigeonholeSort(arr, n); + + printf("Sorted order is : "); + for (int i = 0; i < n; i++) + printf("%d ", arr[i]); + + return 0; +} diff --git a/Sorting/quickSort/cpp/quick.cpp b/Sorting/quickSort/C++/quick_sort.cpp similarity index 84% rename from Sorting/quickSort/cpp/quick.cpp rename to Sorting/quickSort/C++/quick_sort.cpp index c45305ace..f8e2bd635 100644 --- a/Sorting/quickSort/cpp/quick.cpp +++ b/Sorting/quickSort/C++/quick_sort.cpp @@ -12,19 +12,21 @@ int partition(std::vector &A, int start, int end) { if(A[i] <= pivot) { - temp=A[i]; - A[i]=A[partitionIndex]; - A[partitionIndex]=temp; + swap(&A[i], &A[partitionIndex]); partitionIndex++; } } - temp=A[partitionIndex]; // Swap pivot element - A[partitionIndex]=A[end]; // eith element at - A[end]=temp; // partition index + swap(&A[partitionIndex], &A[end]); // partition index return partitionIndex; } +void swapElements(int* elementOne, int* elementTwo) +{ + int temp = *elementOne; + *elementOne = *elementTwo; + *elementTwo = temp; +} std::vector quick_sort(std::vector &A, int start, int end) { /* std::cout<<"Current list : \n"; diff --git a/Sorting/Ramdomized Quicksort/cpp/quicksort_3partition.cpp b/Sorting/quickSort/C++/quick_sort_randomized.cpp similarity index 100% rename from Sorting/Ramdomized Quicksort/cpp/quicksort_3partition.cpp rename to Sorting/quickSort/C++/quick_sort_randomized.cpp diff --git a/Sorting/quickSort/C/QuickSort.c b/Sorting/quickSort/C/quick_sort.c similarity index 100% rename from Sorting/quickSort/C/QuickSort.c rename to Sorting/quickSort/C/quick_sort.c diff --git a/Sorting/quickSort/go/QuickSort.go b/Sorting/quickSort/Go/quick_sort.go similarity index 100% rename from Sorting/quickSort/go/QuickSort.go rename to Sorting/quickSort/Go/quick_sort.go diff --git a/Sorting/quickSort/Java/QuickSort.java b/Sorting/quickSort/Java/quick_sort.java similarity index 100% rename from Sorting/quickSort/Java/QuickSort.java rename to Sorting/quickSort/Java/quick_sort.java diff --git a/Sorting/quickSort/Js/quick-sort.js b/Sorting/quickSort/Javascript/quick_sort.js similarity index 95% rename from Sorting/quickSort/Js/quick-sort.js rename to Sorting/quickSort/Javascript/quick_sort.js index 421b6c6af..ac4590dc1 100644 --- a/Sorting/quickSort/Js/quick-sort.js +++ b/Sorting/quickSort/Javascript/quick_sort.js @@ -1,34 +1,34 @@ -function quick_Sort(origArray) { - if (origArray.length<=1) - { - return origArray; - } - else - { - var left=[],right=[],newArray=[]; - var pivot=origArray.pop(); - var length=origArray.length; - - for (var i=0; i(arr: &mut [T]) { + let len = arr.len(); + _quick_sort(arr, 0, (len - 1) as isize); +} + +fn _quick_sort(arr: &mut [T], low: isize, high: isize) { + if low < high { + let p = partition(arr, low, high); + _quick_sort(arr, low, p - 1); + _quick_sort(arr, p + 1, high); + } +} + +fn partition(arr: &mut [T], low: isize, high: isize) -> isize { + let pivot = high as usize; + let mut store_index = low - 1; + let mut last_index = high; + + loop { + store_index += 1; + while arr[store_index as usize] < arr[pivot] { + store_index += 1; + } + last_index -= 1; + while last_index >= 0 && arr[last_index as usize] > arr[pivot] { + last_index -= 1; + } + if store_index >= last_index { + break; + } else { + arr.swap(store_index as usize, last_index as usize); + } + } + arr.swap(store_index as usize, pivot as usize); + store_index +} +fn main() { + println!("Sort numbers ascending"); + let mut numbers = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1]; + println!("Before: {:?}", numbers); + quick_sort(&mut numbers); + println!("After: {:?}\n", numbers); +} diff --git a/Sorting/quickSort/csharp/QuickSort.cs b/Sorting/quickSort/csharp/QuickSort.cs new file mode 100644 index 000000000..d3c131889 --- /dev/null +++ b/Sorting/quickSort/csharp/QuickSort.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Quicksort +{ + class Program + { + static void Main(string[] args) + { + // Create an unsorted array of string elements + string[] unsorted = { "z", "e", "x", "c", "m", "q", "a" }; + + // Print the unsorted array + for (int i = 0; i < unsorted.Length; i++) + { + Console.Write(unsorted[i] + " "); + } + + Console.WriteLine(); + + // Sort the array + Quicksort(unsorted, 0, unsorted.Length - 1); + + // Print the sorted array + for (int i = 0; i < unsorted.Length; i++) + { + Console.Write(unsorted[i] + " "); + } + + Console.WriteLine(); + + Console.ReadLine(); + } + + public static void Quicksort(IComparable[] elements, int left, int right) + { + int i = left, j = right; + IComparable pivot = elements[(left + right) / 2]; + + while (i <= j) + { + while (elements[i].CompareTo(pivot) < 0) + { + i++; + } + + while (elements[j].CompareTo(pivot) > 0) + { + j--; + } + + if (i <= j) + { + // Swap + IComparable tmp = elements[i]; + elements[i] = elements[j]; + elements[j] = tmp; + + i++; + j--; + } + } + + // Recursive calls + if (left < j) + { + Quicksort(elements, left, j); + } + + if (i < right) + { + Quicksort(elements, i, right); + } + } + + } +} \ No newline at end of file diff --git a/Sorting/quickSort/potigol/quicksort.poti b/Sorting/quickSort/potigol/quicksort.poti new file mode 100644 index 000000000..b88bdfd11 --- /dev/null +++ b/Sorting/quickSort/potigol/quicksort.poti @@ -0,0 +1,18 @@ +# QuickSort + +quicksort(num: Lista[Inteiro]): Lista[Inteiro] = + escolha num + caso [] => [] + caso pivo::resto => + menores = resto.selecione( _ <= pivo ) + maiores = resto.selecione( _ > pivo ) + quicksort(menores) + pivo::quicksort(maiores) + fim + +escreva "Enter some numbers separated by space" +numeros = leia_inteiros(" ") +escreva "The ordered numbers:" +escreva quicksort(numeros) + + +# More about this language: http://potigol.github.io/ \ No newline at end of file diff --git a/Sorting/quickSort/python/quicksort.py b/Sorting/quickSort/python/quick_sort_2.py similarity index 100% rename from Sorting/quickSort/python/quicksort.py rename to Sorting/quickSort/python/quick_sort_2.py diff --git a/Sorting/Ramdomized Quicksort/python/quicksort_3partition.py b/Sorting/quickSort/python/quick_sort_randomized.py similarity index 100% rename from Sorting/Ramdomized Quicksort/python/quicksort_3partition.py rename to Sorting/quickSort/python/quick_sort_randomized.py diff --git a/Sorting/quickSort/scala/QuickSort.scala b/Sorting/quickSort/scala/QuickSort.scala new file mode 100644 index 000000000..aad76d079 --- /dev/null +++ b/Sorting/quickSort/scala/QuickSort.scala @@ -0,0 +1,16 @@ +object QuickSort extends App { + def sort(list: List[Int]): List[Int] = { + list match { + case Nil => Nil + case oneElementList :: Nil => List(oneElementList) + case pivot :: tail => { + val (less, greater) = tail.partition(_ < pivot) + sort(less) ::: pivot :: sort(greater) + } + } + } + val originalList = List(10, 7, 8, 9, 1, 5) + val sortedList = sort(originalList) + println(s"originalList: ${originalList}") + println(s"sortedList: ${sortedList}") +} diff --git a/Sorting/shaker-sort/shaker_sort.js b/Sorting/shaker-sort/shaker_sort.js new file mode 100644 index 000000000..0fe17251c --- /dev/null +++ b/Sorting/shaker-sort/shaker_sort.js @@ -0,0 +1,24 @@ +export const shakerSort = (array) => { + let swapped; + do { + swapped = false; + for (let j = i; j < array.length - i; j++) { + if (array[j] > array[j + 1]) { + let temp = array[j]; + array[j] = array[j + 1]; + array[j + 1] = temp; + swapped = true; + } + } + if (!swapped) return array; + for (let j = array.length - 1; i >= 0; i--) { + if (array[j] < array[j - 1]) { + let temp = array[j]; + array[j] = array[j + 1]; + array[j + 1] = temp; + swapped = true; + } + } + } while (swapped); + return array; +}; diff --git a/Tree/AVLTree/AVL_Tree.cpp b/Tree/AVLTree/AVL_Tree.cpp index 5cea1f113..3790c5fbf 100644 --- a/Tree/AVLTree/AVL_Tree.cpp +++ b/Tree/AVLTree/AVL_Tree.cpp @@ -1,354 +1,151 @@ -#include "AVL.hpp" -#include -using namespace std; - -inline int max(int a, int b) { - return (a>b)? a: b; -} - -template -int height(AVLnode* N) { - if(N== nullptr) - return 0; - return N->height; -} - -template -AVLnode* newNode(Key key, Value value) { - AVLnode* node = (AVLnode*)malloc(sizeof(AVLnode)); - node->key = key; - node->val = value; - node->left = nullptr; - node->right = nullptr; - node->height = 1; - return node; -} - -template -AVLnode* rightRotate(AVLnode *y) { - AVLnode *x = y->left; - AVLnode *T2 = x->right; - x->right = y; - y->left = T2; - y->height = max(height(y->left),height(y->right))+1; - x->height = max(height(x->left),height(x->right))+1; - return x; -} - -template -AVLnode* leftRotate(AVLnode *x) { - AVLnode *y = x->right; - AVLnode *T2 = y->left; - y->left = x; - x->right = T2; - x->height = max(height(x->left),height(x->right))+1; - y->height = max(height(y->left),height(y->right))+1; - return y; -} - -template -int getBalance(AVLnode* N) { - if(N== nullptr) - return 0; - return height(N->left)-height(N->right); -} - -template -AVLnode* insert(AVLnode* node, Key key, Value value) { - if(node== nullptr) - return newNode(key,value); - if (key <= node->key) - node->left = insert(node->left,key,value); - else if(key > node->key) - node->right = insert(node->right,key,value); - else - return node; - - node->height = 1 + max(height(node->left),height(node->right)); - int balance = getBalance(node); - - if(balance>1 && keyleft->key) - return rightRotate(node); - if(balance<-1 && key>node->right->key) - return leftRotate(node); - if(balance>1 && key>node->left->key) { - node->left = leftRotate(node->left); - return rightRotate(node); - } - if(balance<-1 && key < node->right->key) { - node->right = rightRotate(node->right); - return leftRotate(node); - } - return node; -} - -template -AVLnode* minValueNode(AVLnode* node) { - AVLnode* current = node; - while (current->left!= nullptr) - current = current->left; - return current; -} - -template -AVLnode* deleteNode(AVLnode* root, Key key) { - if(root== nullptr) - return root; - if(keykey) - root->left = deleteNode(root->left,key); - else if (key>root->key) - root->right = deleteNode(root->right,key); - else { - if((root->left == nullptr) || (root->right== nullptr)) { - AVLnode* temp = root->left?root->left:root->right; - if(temp== nullptr) { - temp = root; - root = nullptr; - } - else - *root = *temp; - free(temp); - } - else { - AVLnode *temp = minValueNode(root->right); - root->key = temp->key; - root->right = deleteNode(root->right, temp->key); - } - } - - if (root == nullptr) - return root; - - root->height = 1+max(height(root->left),height(root->right)); - int balance = getBalance(root); - if (balance>1 && getBalance(root->left) >=0) - return rightRotate(root); - if(balance>1 && getBalance(root->left) < 0) { - root->left = leftRotate(root->left); - return rightRotate(root); - } - if(balance<-1 && getBalance(root->right) <= 0) - return leftRotate(root); - if(balance<-1 && getBalance(root->right) > 0) { - root->right = rightRotate(root->right); - return leftRotate(root); - } - return root; -} -template -void preOrder(AVLnode *root) { - if(root!= nullptr) { - cout << root->key << " " << root->val << endl; - preOrder(root->left); - preOrder(root->right); - } -} -template -AVLnode* Find(Key key, AVLnode* node) { - if (node->key == key) - return node; - else if (node->key > key) { - if (node->left != nullptr) - return Find(key, node->left); - return node; - } else if (node->key < key) { - if (node->right != nullptr) - return Find(key, node->right); - return node; - } -} -template -void inOrder(AVLnode* node) { - if(node== nullptr) - return; - else { - inOrder(node->left); - cout << node->key << " " << node->val << endl; - inOrder(node->right); - } -} -template -void postOrder(AVLnode* node) { - if(node== nullptr) - return; - else { - postOrder(node->left); - postOrder(node->right); - cout << node->key << " " << node->val << endl; - } -} -template -AVLnode* maxValueNode(AVLnode* node) { - AVLnode* current = node; - while (current->right!= nullptr) - current = current->right; - return current; -} -template -void inOrderPredecesor(AVLnode* root, AVLnode*& pre, Key key) { - if(root== nullptr) return; - if(root->key==key) { - if(root->left!= nullptr) { - pre = maxValueNode(root->left); - } - } - else if(root->key > key) { - inOrderPredecesor(root->left,pre,key); - } - else { - pre = root; - inOrderPredecesor(root->right,pre,key); - } -} -template -void inOrderSuccessor(AVLnode* root, AVLnode*& suc, Key key) { - if(root== nullptr) return; - - if (root->key == key) { - if(root->right!= nullptr) { - AVLnode* tmp = root->right; - while(tmp->left) - tmp = tmp->left; - suc = tmp; - } - } - - else if(root->key > key) { - suc = root; - inOrderSuccessor(root->left,suc,key); - } - else { - inOrderSuccessor(root->right,suc,key); - } -} -template -int count(AVLnode* n) { - int c = 1; - if(n== nullptr) - return 0; - else { - c += count(n->left); - c += count(n->right); - return c; - } -} -template -void AVL::put(const Key &key, const Value &value) { - AVLnode* current = root; - current = insert(current,key,value); - root = current; -} -template -void AVL::print_pre_order() { - AVLnode* current = root; - preOrder(current); - cout << endl; -} -template -void AVL::remove(const Key &key) { - root = deleteNode(root,key); -} -template -Value AVL::get(const Key &key) { - AVLnode* current = root; - return Find(key,current)->val; -} -template -bool AVL::has(const Key &key) { - AVLnode* current=root; - if(Find(key,current)->key==key) - return true; - else - return false; -} -template -Key AVL::successor(const Key &key) { - AVLnode* current = root; - AVLnode* suc = nullptr; - inOrderSuccessor(current,suc,key); - return suc->key; -} -template -Key AVL::predecessor(const Key &key) { - AVLnode* current = root; - AVLnode* pre = nullptr; - inOrderPredecesor(current,pre,key); - return pre->key; -} -template -Key AVL::minimum() { - return minValueNode(root)->key; -} -template -Key AVL::maximum() { - return maxValueNode(root)->key; -} -template -void AVL::print_in_order() { - inOrder(root); -} -template -void AVL::print_post_order() { - postOrder(root); -} -template -int AVL::getHeight() { - return root->height; -} -template -void AVL::print() { - inOrder(root); -} -template -int AVL::size() { - return count(root); -} -template -void q1(AVLnode* root, Key k1, Key k2, Value val, Value& count) { - if(root == nullptr) - return; - if(k1 < root->key) - q1(root->left,k1,k2,val,count); - if(k1 < root->key && k2 >= root->key) { - if(abs(root->val-val)val-val); - } - - if(k2 > root->key) - q1(root->right,k1,k2,val,count); -} -template -Value AVL::que_1(Key &key, Value &val) { - Value count = INT32_MAX; - AVLnode* current = root; - Key max = maximum(); - q1(current,key,max,val,count); - if(count == INT32_MAX) - return -1; - else - return count; -} -template -void q2(AVLnode* root, Key k1, Key k2, Value val, Value& count) { - if(root == nullptr) - return; - if(k1 < root->key) - q2(root->left,k1,k2,val,count); - if(k1 <= root->key && k2 > root->key) { -// cout << root->key << " " << root->val << " "; - if(root->val>val) { - count++; - } - } - - if(k2 > root->key) - q2(root->right,k1,k2,val,count); -} -template -Value AVL::que_2(Key &key, Value &val) { - Value count = 0; - AVLnode *current = root; - Key min = minimum(); - q2(current,min,key,val,count); - return count; -} +// C program to insert a node in AVL tree +#include +#include + +// An AVL tree node +struct Node +{ + int key; + struct Node *left; + struct Node *right; + int height; +}; + +// A utility function to get maximum of two integers +int max(int a, int b); + +// A utility function to get the height of the tree +int height(struct Node *N) +{ + if (N == NULL) + return 0; + return N->height; +} + +// A utility function to get maximum of two integers +int max(int a, int b) +{ + return (a > b)? a : b; +} + +/* Helper function that allocates a new node with the given key and + NULL left and right pointers. */ +struct Node* newNode(int key) +{ + struct Node* node = (struct Node*) + malloc(sizeof(struct Node)); + node->key = key; + node->left = NULL; + node->right = NULL; + node->height = 1; // new node is initially added at leaf + return(node); +} + +struct Node *rightRotate(struct Node *y) +{ + struct Node *x = y->left; + struct Node *T2 = x->right; + + // Perform rotation + x->right = y; + y->left = T2; + + // Update heights + y->height = max(height(y->left), height(y->right))+1; + x->height = max(height(x->left), height(x->right))+1; + + // Return new root + return x; +} + +// A utility function to left rotate subtree rooted with x +// See the diagram given above. +struct Node *leftRotate(struct Node *x) +{ + struct Node *y = x->right; + struct Node *T2 = y->left; + + // Perform rotation + y->left = x; + x->right = T2; + + // Update heights + x->height = max(height(x->left), height(x->right))+1; + y->height = max(height(y->left), height(y->right))+1; + + // Return new root + return y; +} + +// Get Balance factor of node N +int getBalance(struct Node *N) +{ + if (N == NULL) + return 0; + return height(N->left) - height(N->right); +} + + +struct Node* insert(struct Node* node, int key) +{ + /* 1. Perform the normal BST insertion */ + if (node == NULL) + return(newNode(key)); + + if (key < node->key) + node->left = insert(node->left, key); + else if (key > node->key) + node->right = insert(node->right, key); + else // Equal keys are not allowed in BST + return node; + + /* 2. Update height of this ancestor node */ + node->height = 1 + max(height(node->left), + height(node->right)); + + /* 3. Get the balance factor of this ancestor + node to check whether this node became + unbalanced */ + int balance = getBalance(node); + + // If this node becomes unbalanced, then + // there are 4 cases + + // Left Left Case + if (balance > 1 && key < node->left->key) + return rightRotate(node); + + // Right Right Case + if (balance < -1 && key > node->right->key) + return leftRotate(node); + + // Left Right Case + if (balance > 1 && key > node->left->key) + { + node->left = leftRotate(node->left); + return rightRotate(node); + } + + // Right Left Case + if (balance < -1 && key < node->right->key) + { + node->right = rightRotate(node->right); + return leftRotate(node); + } + + /* return the (unchanged) node pointer */ + return node; +} + +// A utility function to print preorder traversal +// of the tree. +// The function also prints height of every node +void preOrder(struct Node *root) +{ + if(root != NULL) + { + printf("%d ", root->key); + preOrder(root->left); + preOrder(root->right); + } +} diff --git a/Tree/Binary Search Tree/BinarySearchTree.swift b/Tree/Binary Search Tree/BinarySearchTree.swift new file mode 100644 index 000000000..34ade3896 --- /dev/null +++ b/Tree/Binary Search Tree/BinarySearchTree.swift @@ -0,0 +1,346 @@ +/* + A binary search tree. + + Each node stores a value and two children. The left child contains a smaller + value; the right a larger (or equal) value. + + This tree allows duplicate elements. + + This tree does not automatically balance itself. To make sure it is balanced, + you should insert new values in randomized order, not in sorted order. +*/ +public class BinarySearchTree { + fileprivate(set) public var value: T + fileprivate(set) public var parent: BinarySearchTree? + fileprivate(set) public var left: BinarySearchTree? + fileprivate(set) public var right: BinarySearchTree? + + public init(value: T) { + self.value = value + } + + public convenience init(array: [T]) { + precondition(array.count > 0) + self.init(value: array.first!) + for v in array.dropFirst() { + insert(value: v) + } + } + + public var isRoot: Bool { + return parent == nil + } + + public var isLeaf: Bool { + return left == nil && right == nil + } + + public var isLeftChild: Bool { + return parent?.left === self + } + + public var isRightChild: Bool { + return parent?.right === self + } + + public var hasLeftChild: Bool { + return left != nil + } + + public var hasRightChild: Bool { + return right != nil + } + + public var hasAnyChild: Bool { + return hasLeftChild || hasRightChild + } + + public var hasBothChildren: Bool { + return hasLeftChild && hasRightChild + } + + /* How many nodes are in this subtree. Performance: O(n). */ + public var count: Int { + return (left?.count ?? 0) + 1 + (right?.count ?? 0) + } +} + +// MARK: - Adding items + +extension BinarySearchTree { + /* + Inserts a new element into the tree. You should only insert elements + at the root, to make to sure this remains a valid binary tree! + Performance: runs in O(h) time, where h is the height of the tree. + */ + public func insert(value: T) { + if value < self.value { + if let left = left { + left.insert(value: value) + } else { + left = BinarySearchTree(value: value) + left?.parent = self + } + } else { + if let right = right { + right.insert(value: value) + } else { + right = BinarySearchTree(value: value) + right?.parent = self + } + } + } +} + +// MARK: - Deleting items + +extension BinarySearchTree { + /* + Deletes a node from the tree. + + Returns the node that has replaced this removed one (or nil if this was a + leaf node). That is primarily useful for when you delete the root node, in + which case the tree gets a new root. + + Performance: runs in O(h) time, where h is the height of the tree. + */ + @discardableResult public func remove() -> BinarySearchTree? { + let replacement: BinarySearchTree? + + // Replacement for current node can be either biggest one on the left or + // smallest one on the right, whichever is not nil + if let right = right { + replacement = right.minimum() + } else if let left = left { + replacement = left.maximum() + } else { + replacement = nil + } + + replacement?.remove() + + // Place the replacement on current node's position + replacement?.right = right + replacement?.left = left + right?.parent = replacement + left?.parent = replacement + reconnectParentTo(node:replacement) + + // The current node is no longer part of the tree, so clean it up. + parent = nil + left = nil + right = nil + + return replacement + } + + private func reconnectParentTo(node: BinarySearchTree?) { + if let parent = parent { + if isLeftChild { + parent.left = node + } else { + parent.right = node + } + } + node?.parent = parent + } +} + +// MARK: - Searching + +extension BinarySearchTree { + /* + Finds the "highest" node with the specified value. + Performance: runs in O(h) time, where h is the height of the tree. + */ + public func search(value: T) -> BinarySearchTree? { + var node: BinarySearchTree? = self + while let n = node { + if value < n.value { + node = n.left + } else if value > n.value { + node = n.right + } else { + return node + } + } + return nil + } + + /* + // Recursive version of search + public func search(value: T) -> BinarySearchTree? { + if value < self.value { + return left?.search(value) + } else if value > self.value { + return right?.search(value) + } else { + return self // found it! + } + } + */ + + public func contains(value: T) -> Bool { + return search(value: value) != nil + } + + /* + Returns the leftmost descendent. O(h) time. + */ + public func minimum() -> BinarySearchTree { + var node = self + while let next = node.left { + node = next + } + return node + } + + /* + Returns the rightmost descendent. O(h) time. + */ + public func maximum() -> BinarySearchTree { + var node = self + while let next = node.right { + node = next + } + return node + } + + /* + Calculates the depth of this node, i.e. the distance to the root. + Takes O(h) time. + */ + public func depth() -> Int { + var node = self + var edges = 0 + while let parent = node.parent { + node = parent + edges += 1 + } + return edges + } + + /* + Calculates the height of this node, i.e. the distance to the lowest leaf. + Since this looks at all children of this node, performance is O(n). + */ + public func height() -> Int { + if isLeaf { + return 0 + } else { + return 1 + max(left?.height() ?? 0, right?.height() ?? 0) + } + } + + /* + Finds the node whose value precedes our value in sorted order. + */ + public func predecessor() -> BinarySearchTree? { + if let left = left { + return left.maximum() + } else { + var node = self + while let parent = node.parent { + if parent.value < value { return parent } + node = parent + } + return nil + } + } + + /* + Finds the node whose value succeeds our value in sorted order. + */ + public func successor() -> BinarySearchTree? { + if let right = right { + return right.minimum() + } else { + var node = self + while let parent = node.parent { + if parent.value > value { return parent } + node = parent + } + return nil + } + } +} + +// MARK: - Traversal + +extension BinarySearchTree { + public func traverseInOrder(process: (T) -> Void) { + left?.traverseInOrder(process: process) + process(value) + right?.traverseInOrder(process: process) + } + + public func traversePreOrder(process: (T) -> Void) { + process(value) + left?.traversePreOrder(process: process) + right?.traversePreOrder(process: process) + } + + public func traversePostOrder(process: (T) -> Void) { + left?.traversePostOrder(process: process) + right?.traversePostOrder(process: process) + process(value) + } + + /* + Performs an in-order traversal and collects the results in an array. + */ + public func map(formula: (T) -> T) -> [T] { + var a = [T]() + if let left = left { a += left.map(formula: formula) } + a.append(formula(value)) + if let right = right { a += right.map(formula: formula) } + return a + } +} + +/* + Is this binary tree a valid binary search tree? +*/ +extension BinarySearchTree { + public func isBST(minValue: T, maxValue: T) -> Bool { + if value < minValue || value > maxValue { return false } + let leftBST = left?.isBST(minValue: minValue, maxValue: value) ?? true + let rightBST = right?.isBST(minValue: value, maxValue: maxValue) ?? true + return leftBST && rightBST + } +} + +// MARK: - Debugging + +extension BinarySearchTree: CustomStringConvertible { + public var description: String { + var s = "" + if let left = left { + s += "(\(left.description)) <- " + } + s += "\(value)" + if let right = right { + s += " -> (\(right.description))" + } + return s + } + + public func toArray() -> [T] { + return map { $0 } + } + +} + +//extension BinarySearchTree: CustomDebugStringConvertible { +// public var debugDescription: String { +// var s = "" +// if let left = left { +// s += "(\(left.description)) <- " +// } +// s += "\(value)" +// if let right = right { +// s += " -> (\(right.description))" +// } +// return s +// } +//} diff --git a/Tree/Binary Search Tree/Binary_Search_Tree.cpp b/Tree/Binary Search Tree/Binary_Search_Tree.cpp new file mode 100644 index 000000000..b79d7e07f --- /dev/null +++ b/Tree/Binary Search Tree/Binary_Search_Tree.cpp @@ -0,0 +1,373 @@ +/* + * C++ Program To Implement BST + */ +# include +# include +using namespace std; +/* + * Node Declaration + */ +struct node +{ + int info; + struct node *left; + struct node *right; +}*root; + +/* + * Class Declaration + */ +class BST +{ + public: + void find(int, node **, node **); + void insert(int); + void del(int); + void case_a(node *,node *); + void case_b(node *,node *); + void case_c(node *,node *); + void preorder(node *); + void inorder(node *); + void postorder(node *); + void display(node *, int); + BST() + { + root = NULL; + } +}; +/* + * Main Contains Menu + */ +int main() +{ + int choice, num; + BST bst; + node *temp; + while (1) + { + cout<<"-----------------"<>choice; + switch(choice) + { + case 1: + temp = new node; + cout<<"Enter the number to be inserted : "; + cin>>temp->info; + bst.insert(root, temp); + case 2: + if (root == NULL) + { + cout<<"Tree is empty, nothing to delete"<>num; + bst.del(num); + break; + case 3: + cout<<"Inorder Traversal of BST:"<info) + { + *loc = root; + *par = NULL; + return; + } + if (item < root->info) + ptr = root->left; + else + ptr = root->right; + ptrsave = root; + while (ptr != NULL) + { + if (item == ptr->info) + { + *loc = ptr; + *par = ptrsave; + return; + } + ptrsave = ptr; + if (item < ptr->info) + ptr = ptr->left; + else + ptr = ptr->right; + } + *loc = NULL; + *par = ptrsave; +} + +/* + * Inserting Element into the Tree + */ +void BST::insert(node *tree, node *newnode) +{ + if (root == NULL) + { + root = new node; + root->info = newnode->info; + root->left = NULL; + root->right = NULL; + cout<<"Root Node is Added"<info == newnode->info) + { + cout<<"Element already in the tree"<info > newnode->info) + { + if (tree->left != NULL) + { + insert(tree->left, newnode); + } + else + { + tree->left = newnode; + (tree->left)->left = NULL; + (tree->left)->right = NULL; + cout<<"Node Added To Left"<right != NULL) + { + insert(tree->right, newnode); + } + else + { + tree->right = newnode; + (tree->right)->left = NULL; + (tree->right)->right = NULL; + cout<<"Node Added To Right"<left == NULL && location->right == NULL) + case_a(parent, location); + if (location->left != NULL && location->right == NULL) + case_b(parent, location); + if (location->left == NULL && location->right != NULL) + case_b(parent, location); + if (location->left != NULL && location->right != NULL) + case_c(parent, location); + free(location); +} + +/* + * Case A + */ +void BST::case_a(node *par, node *loc ) +{ + if (par == NULL) + { + root = NULL; + } + else + { + if (loc == par->left) + par->left = NULL; + else + par->right = NULL; + } +} + +/* + * Case B + */ +void BST::case_b(node *par, node *loc) +{ + node *child; + if (loc->left != NULL) + child = loc->left; + else + child = loc->right; + if (par == NULL) + { + root = child; + } + else + { + if (loc == par->left) + par->left = child; + else + par->right = child; + } +} + +/* + * Case C + */ +void BST::case_c(node *par, node *loc) +{ + node *ptr, *ptrsave, *suc, *parsuc; + ptrsave = loc; + ptr = loc->right; + while (ptr->left != NULL) + { + ptrsave = ptr; + ptr = ptr->left; + } + suc = ptr; + parsuc = ptrsave; + if (suc->left == NULL && suc->right == NULL) + case_a(parsuc, suc); + else + case_b(parsuc, suc); + if (par == NULL) + { + root = suc; + } + else + { + if (loc == par->left) + par->left = suc; + else + par->right = suc; + } + suc->left = loc->left; + suc->right = loc->right; +} + +/* + * Pre Order Traversal + */ +void BST::preorder(node *ptr) +{ + if (root == NULL) + { + cout<<"Tree is empty"<info<<" "; + preorder(ptr->left); + preorder(ptr->right); + } +} +/* + * In Order Traversal + */ +void BST::inorder(node *ptr) +{ + if (root == NULL) + { + cout<<"Tree is empty"<left); + cout<info<<" "; + inorder(ptr->right); + } +} + +/* + * Postorder Traversal + */ +void BST::postorder(node *ptr) +{ + if (root == NULL) + { + cout<<"Tree is empty"<left); + postorder(ptr->right); + cout<info<<" "; + } +} + +/* + * Display Tree Structure + */ +void BST::display(node *ptr, int level) +{ + int i; + if (ptr != NULL) + { + display(ptr->right, level+1); + cout<: "; + else + { + for (i = 0;i < level;i++) + cout<<" "; + } + cout<info; + display(ptr->left, level+1); + } +} diff --git a/Tree/Binary Search Tree/Bst to min heap.cpp b/Tree/Binary Search Tree/Bst to min heap.cpp new file mode 100644 index 000000000..83f1c53e0 --- /dev/null +++ b/Tree/Binary Search Tree/Bst to min heap.cpp @@ -0,0 +1,115 @@ +//Given a binary search tree which is also a complete binary tree. The problem is to convert the given BST into a Min Heap +//with the condition that all the values in the left subtree of a node should be less than all the values in the right subtree of the node. +/This condition is applied on all the nodes in the so converted Min Heap. + +#include +using namespace std; + +// structure of a node of BST +struct Node +{ + int data; + Node *left, *right; +}; + +/* Helper function that allocates a new node + with the given data and NULL left and right + pointers. */ +struct Node* getNode(int data) +{ + struct Node *newNode = new Node; + newNode->data = data; + newNode->left = newNode->right = NULL; + return newNode; +} + +// function prototype for preorder traversal +// of the given tree +void preorderTraversal(Node*); + +// function for the inorder traversal of the tree +// so as to store the node values in 'arr' in +// sorted order +void inorderTraversal(Node *root, vector& arr) +{ + if (root == NULL) + return; + + // first recur on left subtree + inorderTraversal(root->left, arr); + + // then copy the data of the node + arr.push_back(root->data); + + // now recur for right subtree + inorderTraversal(root->right, arr); +} + +// function to convert the given BST to MIN HEAP +// performs preorder traversal of the tree +void BSTToMinHeap(Node *root, vector arr, int *i) +{ + if (root == NULL) + return; + + // first copy data at index 'i' of 'arr' to + // the node + root->data = arr[++*i]; + + // then recur on left subtree + BSTToMinHeap(root->left, arr, i); + + // now recur on right subtree + BSTToMinHeap(root->right, arr, i); +} + +// utility function to convert the given BST to +// MIN HEAP +void convertToMinHeapUtil(Node *root) +{ + // vector to store the data of all the + // nodes of the BST + vector arr; + int i = -1; + + // inorder traversal to populate 'arr' + inorderTraversal(root, arr); + + // BST to MIN HEAP conversion + BSTToMinHeap(root, arr, &i); +} + +// function for the preorder traversal of the tree +void preorderTraversal(Node *root) +{ + if (!root) + return; + + // first print the root's data + cout << root->data << " "; + + // then recur on left subtree + preorderTraversal(root->left); + + // now recur on right subtree + preorderTraversal(root->right); +} + +// Driver program to test above +int main() +{ + // BST formation + struct Node *root = getNode(4); + root->left = getNode(2); + root->right = getNode(6); + root->left->left = getNode(1); + root->left->right = getNode(3); + root->right->left = getNode(5); + root->right->right = getNode(7); + + convertToMinHeapUtil(root); + cout << "Preorder Traversal:" << endl; + preorderTraversal(root); + + return 0; +} diff --git a/Tree/Binary Search Tree/Ruby/bst.rb b/Tree/Binary Search Tree/Ruby/bst.rb new file mode 100644 index 000000000..25cb26d36 --- /dev/null +++ b/Tree/Binary Search Tree/Ruby/bst.rb @@ -0,0 +1,111 @@ +class BinarySearchTree + class Node + attr_reader :key, :left, :right + def initialize( key ) + @key = key + @left = nil + @right = nil + end + + def insert( new_key ) + if new_key <= @key + @left.nil? ? @left = Node.new( new_key ) : @left.insert( new_key ) + elsif new_key > @key + @right.nil? ? @right = Node.new( new_key ) : @right.insert( new_key ) + end + end + end + + def initialize + @root = nil + end + + def insert( key ) + if @root.nil? + @root = Node.new( key ) + else + @root.insert( key ) + end + end + + def in_order(node=@root, &block) + return if node.nil? + in_order(node.left, &block) + yield node + in_order(node.right, &block) + end + + def pre_order(node=@root, &block) + return if node.nil? + yield node + in_order(node.left, &block) + in_order(node.right, &block) + end + + def post_order(node=@root, &block) + return if node.nil? + in_order(node.left, &block) + in_order(node.right, &block) + yield node + end + + def search( key, node=@root ) + return nil if node.nil? + if key < node.key + search( key, node.left ) + elsif key > node.key + search( key, node.right ) + else + return node + end + end + + def check_height(node) + return 0 if node.nil? + + leftHeight = check_height(node.left) + return -1 if leftHeight == -1 + + rightHeight = check_height(node.right) + return -1 if rightHeight == -1 + + diff = leftHeight - rightHeight + if diff.abs > 1 + -1 + else + [leftHeight, rightHeight].max + 1 + end + end + + def is_balanced?(node=@root) + check_height(node) == -1 ? false : true + end + +end + +tree = BinarySearchTree.new +tree.insert(50) +tree.insert(25) +tree.insert(75) +tree.insert(12) +tree.insert(37) +tree.insert(87) +tree.insert(63) +puts tree.inspect +puts "tree.is_balanced?" +puts tree.is_balanced? + +puts "pre_order" +tree.pre_order do |node| + puts node.key +end + +puts "in_order" +tree.in_order do |node| + puts node.key +end + +puts "post_order" +tree.post_order do |node| + puts node.key +end diff --git a/Tree/Binary Search Tree/binary_tree_mirror.cpp b/Tree/Binary Search Tree/binary_tree_mirror.cpp new file mode 100644 index 000000000..a4680dde6 --- /dev/null +++ b/Tree/Binary Search Tree/binary_tree_mirror.cpp @@ -0,0 +1,65 @@ +#include +using namespace std; + +struct node{ + int data; + struct node*left; + struct node*right; +}; + +struct node* insert(int d,struct node*root){ + if(root ==NULL){ + struct node*temp = (struct node*) malloc(sizeof(struct node)); + temp->data=d; + temp->left=NULL; + temp->right=NULL; + return temp; + } + else if(d >root->data){ + root->right= insert(d,root->right); + } + else{ + root->left = insert(d,root->left); + } + return root; +} + +void inorder(struct node*root){ + if(root==NULL){ + return; + } + inorder(root->left); + printf("%d",root->data); + inorder(root->right); +} + +void mirror(struct node*root){ + if(root==NULL){ + return; + } + else{ + mirror(root->left); + mirror(root->right); + struct node*temp; + temp=root->left; + root->left=root->right; + root->right=temp; + } +} + +int main(){ + int n; + cin>>n; + int a[n]; + struct node*root = NULL; + for(int i=0;i>a[i]; + } + for(int i=0;i curr.value: + prev = curr + curr = curr.right + last = "R" + else: + raise Error("Duplicate value already exists in tree!") + + if last == "L": + prev.left = TreeNode(value) + else: + prev.right = TreeNode(value) + + + #-------------------------------------------------------------------------------- + # Gets the root of the tree + def getRoot(self): + return self.root + + + #-------------------------------------------------------------------------------- + # Looks for a value in the tree (Recursive) + # Returns None if not found else returns the node found + def search_rec(self, tree, target): + if tree is not None: + if target == tree.value: + return tree + elif target < tree.value: + return self.search_rec(tree.left, target) + else: + return self.search_rec(tree.right, target) + + + #-------------------------------------------------------------------------------- + # Looks for a value in the tree (Non-recursive) + # Returns None if not found else returns the node found + def search(self, tree, target): + if self.root is None: + print("Binary tree is empty.") + return None + else: + curr = self.root + found = False + + while curr is not None and not found: + if target == curr.value: + found = True + return curr + elif target < curr.value: + curr = curr.left + else: + curr = curr.right + + return None if not found + + + #-------------------------------------------------------------------------------- + # Gets the parent of the specified node to search for + def getParent(self, curNode, target, parent): + if curNode == None: + return None + elif curNode.value == target.value: + return parent + else: + if target.value < curNode.value: + return self.getParent(curNode.left, target, curNode) + elif target.value > curNode.value: + return self.getParent(curNode.right, target, curNode) + + + #-------------------------------------------------------------------------------- + # Non-recursive deletion + def delete(self, tree, target): + + nodeToDel = self.search(tree, target) # search for the node + if nodeToDel == None: + print (target,'does not exist !') + return + + nodeParent = self.getParent(tree, nodeToDel, None) # get parent of the node to be deleted + + if (nodeToDel.left and nodeToDel.right) != None: # node to be deleted has two children + + # find predecseeor + predNode = nodeToDel.left + while predNode.right != None: + predNode = predNode.right + + # set value of the node to be deleted to the value of the predecessor node + nodeToDel.value = predNode.value + + # delete the predecessor node + if nodeToDel.left == predNode : + nodeToDel.left = predNode.left + # del predNode # delete the predecessor node + else: + self.delete(nodeToDel.left, predNode.value) + + else: # node to be deleted has at most 1 child + # set the parent left/right pointer + if nodeToDel.left == None: + if nodeParent.left == nodeToDel: + nodeParent.left = nodeToDel.right + else: + nodeParent.right = nodeToDel.right + else: + if nodeParent.left == nodeToDel: + nodeParent.left = nodeToDel.left + else: + nodeParent.right = nodeToDel.left + # del nodeToDel # delete the node + + + #-------------------------------------------------------------------------------- + # Gets the size of the tree, i.e. number of nodes + def size(self, tree): + if tree == None: + return 0 + else: + return self.size(tree.left) + 1 + self.size(tree.right) + + + #-------------------------------------------------------------------------------- + # Gets the height of the tree + def maxDepth(self, tree): + if tree == None: + return -1 + else: + # computes the two depths + lDepth = self.maxDepth(tree.left) + rDepth = self.maxDepth(tree.right) + # returns the appropriate depth + return max(lDepth, rDepth) + 1 + + + #-------------------------------------------------------------------------------- + # Returns True if binary tree is height-balanced + def isBalanced (self, tree): + if tree == None: + return True + + lh = self.maxDepth(tree.left) # height of left subtree + rh = self.maxDepth(tree.right) # height of right subtree + + if abs(lh-rh) <= 1 and \ + self.isBalanced(tree.left) and \ + self.isBalanced(tree.right): + return True + else: + return False + + + #-------------------------------------------------------------------------------- + # Gets the minimum value + def minValue(self, tree): + # goes down into the left arm and returns the last value + curNode = tree + while curNode.left != None: + curNode = curNode.left + return curNode.value + + + #-------------------------------------------------------------------------------- + # Gets the maximum value + def maxValue(self, tree): + # goes down into the right arm and returns the last value + curr = tree + while curr.right is not None: + curr = curr.right + + return curr.value + + + #-------------------------------------------------------------------------------- + # Prints the tree in inOrder -- ascending order + def printTree(self, tree): + if tree is not None: + self.printTree(tree.left) + print(tree.value, end = ' ') + self.printTree(tree.right) + + + #-------------------------------------------------------------------------------- + # Prints the tree in preOrder + def printTree_preOrder(self, tree): + if tree != None: + print (tree.value, end = ' ') + self.printTree_preOrder(tree.left) + self.printTree_preOrder(tree.right) + + + #-------------------------------------------------------------------------------- + # Prints the tree in postOrder + def printTree_postOrder(self, tree): + def printTree(self, tree): + if tree is not None: + self.printTree(tree.left) + self.printTree(tree.right) + print(tree.value, end = ' ') + + + #-------------------------------------------------------------------------------- + # Prints the tree in reverseOrder -- descending order + def printTree_reverseOrder(self, tree): + if tree is not None: + self.printTree_reverseOrder(tree.right) + print(tree.value, end = ' ') + self.printTree_reverseOrder(tree.left) + + +#==================================================================================== +def main(): + # Instantiate the binary search tree + tree = BSTree() + + # Insert tree nodes to binary search tree + numNodes = int(input("\nEnter number of tree nodes: ")) + print () + for i in range(1, numNodes+1): + value = int(input("Enter value of node %d: " % (i))) + tree.insert(tree.getRoot(), value) + print () + + # Delete a child + value = int(input("Enter the value to be deleted: ")) + tree.delete(tree.getRoot(),value) + print () + + # Print the tree in inOrder + print ('InOrder:\t', end = ' ') + tree.printTree(tree.getRoot()) + print () + + # Print the tree in preOrder + print ('PreOrder:\t', end = ' ') + tree.printTree_preOrder(tree.getRoot()) + print () + + # Print the tree in postOrder + print ('PostOrder:\t', end = ' ') + tree.printTree_postOrder(tree.getRoot()) + print () + + # Print the tree in reverseOrder + print ('ReverseOrder:\t', end = ' ') + tree.printTree_reverseOrder(tree.getRoot()) + print () + + # Looks for a value in the tree + value = int(input("\nEnter a value to find: ")) + if tree.search(tree.getRoot(), value) != None: + print (value,'is found in the tree') + else: + print (value,'is not found in the tree') + + # Print maxDepth, maxValue, minValue and the size of the tree + print ('\nMax depth:',tree.maxDepth(tree.getRoot())) + print ('Max value:',tree.maxValue(tree.getRoot())) + print ('Min value:',tree.minValue(tree.getRoot())) + print ('Size:', tree.size(tree.getRoot())) + print () + + # Print whether the tree is balanced + if tree.isBalanced(tree.getRoot()): + print ('Tree is balanced') + else: + print ('Tree is not balanced') + +main() diff --git a/Tree/Binary Search Tree/go/src/bst.go b/Tree/Binary Search Tree/go/src/bst.go new file mode 100644 index 000000000..3ab9eed83 --- /dev/null +++ b/Tree/Binary Search Tree/go/src/bst.go @@ -0,0 +1,166 @@ +package bst + +import ( + "errors" +) + +type Node struct { + Value string + Data string + Left *Node + Right *Node +} + +// insert into node +func (n *Node) Insert(value, data string) error { + if n == nil { + return errors.New("Cannot insert a value into a nil tree") + } + + switch { + case value == n.Value: + return nil + case value < n.Value: + if n.Left == nil { + n.Left = &Node{Value: value, Data: data} + return nil + + } + return n.Left.Insert(value, data) + + case value < n.Value: + if n.Right == nil { + n.Right = &Node{Value: value, Data: data} + return nil + } + + return n.Right.Insert(value, data) + } + return nil +} + +// find element +func (n *Node) Find(s string) (string, bool) { + if n == nil { + return "", false + } + + switch { + case s == n.Value: + return n.Data, true + case s < n.Value: + return n.Left.Find(s) + default: + return n.Right.Find(s) + } +} + +func (n *Node) findMax(parent *Node) (*Node, *Node) { + if n == nil { + return nil, parent + } + + if n.Right == nil { + return n, parent + } + + return n.Right.findMax(n) +} + +func (n *Node) replaceNode(parent, replacement *Node) error { + if n == nil { + return errors.New("replaceNode() not allowed on a nil node") + } + + if n == parent.Left { + parent.Left = replacement + return nil + } + + parent.Right = replacement + return nil +} + +func (n *Node) Delete(s string, parent *Node) error { + if n == nil { + return errors.New("Value to be deleted does not exist in the tree") + } + + switch { + case s < n.Value: + return n.Left.Delete(s, n) + case s > n.Value: + return n.Right.Delete(s, n) + default: + if n.Left == nil && n.Right == nil { + n.replaceNode(parent, nil) + return nil + } + + if n.Left == nil { + n.replaceNode(parent, n.Right) + return nil + } + + if n.Right == nil { + n.replaceNode(parent, n.Left) + return nil + } + + replacement, replParent := n.Left.findMax(n) + + n.Value = replacement.Value + n.Data = replacement.Data + + return replacement.Delete(replacement.Value, replParent) + } +} + +type Tree struct { + Root *Node +} + +func (t *Tree) Insert(value, data string) error { + if t.Root == nil { + t.Root = &Node{Value: value, Data: data} + return nil + } + + return t.Root.Insert(value, data) +} + +func (t *Tree) Find(s string) (string, bool) { + if t.Root == nil { + return "", false + } + + return t.Root.Find(s) +} + +func (t *Tree) Delete(s string) error { + if t.Root == nil { + return errors.New("Cannot delete from an empty tree") + } + + fakeParent := &Node{Right: t.Root} + err := t.Root.Delete(s, fakeParent) + if err != nil { + return err + } + + if fakeParent.Right == nil { + t.Root = nil + } + return nil +} + +func (t *Tree) Traverse(n *Node, f func(*Node)) { + if n == nil { + return + } + t.Traverse(n.Left, f) + f(n) + t.Traverse(n.Right, f) +} + +// Thank you to https://appliedgo.net/bintree/ diff --git a/Tree/Binary Search Tree/tree_delete_node.cpp b/Tree/Binary Search Tree/tree_delete_node.cpp new file mode 100644 index 000000000..bc717b24c --- /dev/null +++ b/Tree/Binary Search Tree/tree_delete_node.cpp @@ -0,0 +1,145 @@ + +#include +#include + +struct node +{ + int key; + struct node *left, *right; +}; + +// A utility function to create a new BST node +struct node *newNode(int item) +{ + struct node *temp = (struct node *)malloc(sizeof(struct node)); + temp->key = item; + temp->left = temp->right = NULL; + return temp; +} + +// A utility function to do inorder traversal of BST +void inorder(struct node *root) +{ + if (root != NULL) + { + inorder(root->left); + printf("%d ", root->key); + inorder(root->right); + } +} + +/* A utility function to insert a new node with given key in BST */ +struct node* insert(struct node* node, int key) +{ + /* If the tree is empty, return a new node */ + if (node == NULL) return newNode(key); + + /* Otherwise, recur down the tree */ + if (key < node->key) + node->left = insert(node->left, key); + else + node->right = insert(node->right, key); + + /* return the (unchanged) node pointer */ + return node; +} + +/* Given a non-empty binary search tree, return the node with minimum + key value found in that tree. Note that the entire tree does not + need to be searched. */ +struct node * minValueNode(struct node* node) +{ + struct node* current = node; + + /* loop down to find the leftmost leaf */ + while (current->left != NULL) + current = current->left; + + return current; +} + +/* Given a binary search tree and a key, this function deletes the key + and returns the new root */ +struct node* deleteNode(struct node* root, int key) +{ + // base case + if (root == NULL) return root; + + // If the key to be deleted is smaller than the root's key, + // then it lies in left subtree + if (key < root->key) + root->left = deleteNode(root->left, key); + + // If the key to be deleted is greater than the root's key, + // then it lies in right subtree + else if (key > root->key) + root->right = deleteNode(root->right, key); + + // if key is same as root's key, then This is the node + // to be deleted + else + { + // node with only one child or no child + if (root->left == NULL) + { + struct node *temp = root->right; + free(root); + return temp; + } + else if (root->right == NULL) + { + struct node *temp = root->left; + free(root); + return temp; + } + + // node with two children: Get the inorder successor (smallest + // in the right subtree) + struct node* temp = minValueNode(root->right); + + // Copy the inorder successor's content to this node + root->key = temp->key; + + // Delete the inorder successor + root->right = deleteNode(root->right, temp->key); + } + return root; +} + +// Driver Program to test above functions +int main() +{ + /* Let us create following BST + 50 + / \ + 30 70 + / \ / \ + 20 40 60 80 */ + struct node *root = NULL; + root = insert(root, 50); + root = insert(root, 30); + root = insert(root, 20); + root = insert(root, 40); + root = insert(root, 70); + root = insert(root, 60); + root = insert(root, 80); + + printf("Inorder traversal of the given tree \n"); + inorder(root); + + printf("\nDelete 20\n"); + root = deleteNode(root, 20); + printf("Inorder traversal of the modified tree \n"); + inorder(root); + + printf("\nDelete 30\n"); + root = deleteNode(root, 30); + printf("Inorder traversal of the modified tree \n"); + inorder(root); + + printf("\nDelete 50\n"); + root = deleteNode(root, 50); + printf("Inorder traversal of the modified tree \n"); + inorder(root); + + \ No newline at end of file diff --git a/Tree/Binary Tree/BinaryTree.java b/Tree/Binary Tree/BinaryTree.java new file mode 100644 index 000000000..0f4ff01ae --- /dev/null +++ b/Tree/Binary Tree/BinaryTree.java @@ -0,0 +1,63 @@ +import java.util.*; +// Binary Tree implementation using array. +class Tree { + int size; + int ar[] ; + Tree(int size) { + this.size = size; + ar = new int[size]; + } + + void setRoot(int data) { + ar[0] = data; + } + + void setLeft(int data, int parent) { + if(ar[parent] == 0) { + System.out.println("Invalid"); + return; + } + int child = 2*parent + 1; + if(child < 10) { + ar[child] = data; + return; + } + System.out.println("Overflow"); + } + + void setRight(int data, int parent) { + if(ar[parent] == 0) { + System.out.println("Invalid"); + return; + } + int child = 2*parent + 2; + if(child < 10) { + ar[child] = data; + return; + } + System.out.println("Overflow"); + } + public void printTree(int size){ + for (int i = 0; i < size; i++) { + if (ar[i] != 0) + System.out.print(ar[i]+" "); + else + System.out.print("_"+" "); + } + } +} +class BinaryTree { + public static void main(String[] args) { + Scanner Sc = new Scanner(System.in); + System.out.println("Enter the size: "); + int size = Sc.nextInt(); + Tree T = new Tree(size); + T.setRoot(1); + T.setLeft(2,0); + T.setRight(5,0); + T.setLeft(20,1); + T.setRight(10,1); + T.setLeft(23,3); + T.printTree(size); + } +} diff --git a/Tree/CentroidofaTree.cpp b/Tree/CentroidofaTree.cpp new file mode 100644 index 000000000..6f9d254f3 --- /dev/null +++ b/Tree/CentroidofaTree.cpp @@ -0,0 +1,45 @@ +#include +using namespace std; +/* +Centroid of a Tree is a node which if removed from the tree would split it into a ‘forest’, +such that any tree in the forest would have at most half the number of vertices in the original tree. +*/ +unordered_map> l; +int n,m,x,y; +vector centroid; +int *sz; +void dfs(int x,int prev){ + sz[x] = 1; + bool iscentroid = true; + for(auto i:l[x]){ + if(i!=prev){ + dfs(i,x); + sz[x]+=sz[i]; + if(sz[i]>n/2){ + iscentroid = false; + } + } + } + if(n-sz[x] > n/2){ + iscentroid = false; + } + if(iscentroid){ + centroid.push_back(x); + } +} +int32_t main(){ + cin>>n; + for(int i=0;i>x>>y; + x--;y--; + l[x].push_back(y); + l[y].push_back(x); + } + sz = new int[n];//could be dclared globaly where n is maximum number of vertices + dfs(1,-1); + //Every tree has atleast 1 centroid and atmost 2 centroid + for(auto i:centroid){ + cout<= '0' && symbol <= '9' || symbol >= 'A' + && symbol <= 'Z' || symbol >= 'a' && symbol <= 'z') + { + newNode = new Node(symbol); + stk.push(newNode); + } else if (symbol == '+' || symbol == '-' || symbol == '/' + || symbol == '*') + { + Node ptr1 = stk.pop(); + Node ptr2 = stk.pop(); + newNode = new Node(symbol); + newNode.leftChild = ptr2; + newNode.rightChild = ptr1; + stk.push(newNode); + } + symbol = s.charAt(++i); + } + root = stk.pop(); + } + + public void traverse(int type) + { + switch (type) + { + case 1: + System.out.print("Preorder Traversal:- "); + preOrder(root); + break; + case 2: + System.out.print("Inorder Traversal:- "); + inOrder(root); + break; + case 3: + System.out.print("Postorder Traversal:- "); + postOrder(root); + break; + default: + System.out.println("Invalid Choice"); + } + } + private void preOrder(Node localRoot) + { + if (localRoot != null) + { + localRoot.displayNode(); + preOrder(localRoot.leftChild); + preOrder(localRoot.rightChild); + } + } + + private void inOrder(Node localRoot) + { + if (localRoot != null) + { + inOrder(localRoot.leftChild); + localRoot.displayNode(); + inOrder(localRoot.rightChild); + } + } + + private void postOrder(Node localRoot) + { + if (localRoot != null) + { + postOrder(localRoot.leftChild); + postOrder(localRoot.rightChild); + localRoot.displayNode(); + } + } +} + +public class Expression_tree +{ + public static void main(String args[]) + { + String ch = "y"; + Scanner sc=new Scanner(System.in); + while (ch.equals("y")) + { + Tree t1 = new Tree(); + System.out.println("Enter the Expression"); + String a = sc.nextLine(); + t1.insert(a); + t1.traverse(1); + System.out.println(""); + t1.traverse(2); + System.out.println(""); + t1.traverse(3); + System.out.println(""); + System.out.print("Enter y to continue "); + ch = sc.nextLine(); + } + } +} +/* +run: +Enter the Expression +234++5*4/ +Preorder Traversal:- +2/+34*54 +Inorder Traversal:- 2+3+4/5*4 +Postorder Traversal:- 234+54*/ diff --git a/Tree/Fenwick/fenwick.py b/Tree/Fenwick/fenwick.py new file mode 100644 index 000000000..3ce855a84 --- /dev/null +++ b/Tree/Fenwick/fenwick.py @@ -0,0 +1,50 @@ + +class fenwick: + + # Returns sum of arr[0..index]. This function assumes + # that the array is preprocessed and partial sums of + # array elements are stored in __Fenwick[]. + def getsum(i): + s = 0 #initialize result + + # index in __Fenwick[] is 1 more than the index in arr[] + i = i+2 + + # Traverse ancestors of __Fenwick[index] + while i > 0: + + # Add current element of __Fenwick to sum + s += self.__Fenwick[i] + + # Move index to parent node in getSum View + i -= i & (-i) + return s + + + # Updates a node in Fenwick tree at given index + # in __Fenwick. The given value 'val' is added to __Fenwick[i] and + # all of its ancestors in tree. + def updatebit(n , i ,v): + + # index in __Fenwick[] is 1 more than the index in arr[] + i += 2 + + # Traverse all ancestors and add 'val' + while i <= n: + + # Add 'val' to current node of fenwick Tree + self.__Fenwick[i] += v + + # Update index to that of parent in update View + i += i & (-i) + + + + def construct(arr, n): + + # Create and initialize __Fenwick[] as 0 + self.__Fenwick = [0]*(n+1) + + # Store the actual values in __Fenwick[] using update() + for i in range(n): + self.updatebit(n, i, arr[i]) diff --git a/Tree/Heavy Light Decomposition/hld.cpp b/Tree/Heavy Light Decomposition/hld.cpp new file mode 100644 index 000000000..6ed7d3e94 --- /dev/null +++ b/Tree/Heavy Light Decomposition/hld.cpp @@ -0,0 +1,157 @@ +#include +#define maxn 100001 +using namespace std; +vectorv[maxn],arr[maxn],t[maxn]; +int p[maxn],d[maxn],sz[maxn],nxt[maxn],a[maxn],chain[maxn],szc[maxn],st[maxn],top[maxn],nd=0,tim=0,seg[4*maxn+1],lazy[4*maxn+1],n; +int dfs(int s,int r) +{ + p[s]=r; + d[s]=d[r]+1; + sz[s]=1; + for(int i=0;isz[nxt[s]]) + nxt[s]=x; + } + return sz[s]; +} +void hld(int s,int pp=0) +{ + chain[s]=nd; + st[s]=++tim; + if(!szc[nd]) + {top[nd]=s;} + szc[nd]++; + + if(nxt[s]!=-1) + hld(nxt[s],s); + + for(int i=0;ien || rr || seg[x]) + return ; + if(l<=st && en<=r) + { + seg[x]=val; + if(st!=en) + { + if(!seg[2*x]) + lazy[2*x]=val; + if(!seg[2*x+1]) + lazy[2*x+1]=val; + } + return ; + } + int mid=(st+en)/2; + update(2*x,st,mid,l,r,val); + update(2*x+1,mid+1,en,l,r,val); + if(seg[2*x] && seg[2*x+1] && !seg[x]) + seg[x]=seg[2*x]; +} +void go(int x,int y,int val) +{ + int sx=st[x],sy=st[y],sny,snx; + while(chain[x]!=chain[y]) + { + if(d[top[chain[x]]]d[y])swap(x,y); + snx=st[x];sny=st[y]; + if(st[x]==sx || st[x]==sy)snx=st[x]+1; + if(st[y]==sx || st[y]==sy)sny=st[y]-1; + update(1,1,n,snx,sny,val); +} +int qry(int x,int l,int r,int ind) +{ + if(lazy[x]) + { + seg[x]=lazy[x]; + if(l!=r) + { + if(!seg[2*x]) + lazy[2*x]=lazy[x]; + if(!seg[2*x+1]) + lazy[2*x+1]=lazy[x]; + } + lazy[x]=0; + } + if(indr) + return 0; + + if(l==r) + return seg[x]; + int mid=(l+r)/2; + return (qry(2*x,l,mid,ind)+qry(2*x+1,mid+1,r,ind)); +} +int main() +{ + ios_base::sync_with_stdio(false); + cin.tie(0); + cout.tie(0); + int x,y; + for(int i=1;i<=maxn;i++) + for(int j=i;j<=maxn;j+=i) + v[j].push_back(i); + cin>>n; + for(int i=1;i<=n;i++) + { + cin>>a[i]; + for(int j=0;j>x>>y; + t[x].push_back(y); + t[y].push_back(x); + } + memset(p,-1,sizeof(p)); + memset(nxt,-1,sizeof(nxt)); + memset(chain,-1,sizeof(chain)); + dfs(1,0);p[1]=-1; + hld(1); + for(int i=maxn;i>=1;i--) + if(arr[i].size()>1) + { + + x=arr[i][0];y=arr[i][arr[i].size()-1]; + for(int j=1;j +#include + +int sum(int freq[],int i,int j); + +int optCost(int freq[],int i,int j){ + if(j key) + { + // Key is not in tree, we are done + if (root.left == null) return root; + + // Zig-Zig (Left Left) + if (root.left.key > key) + { + // First recursively bring the + // key as root of left-left + root.left.left = splay(root.left.left, key); + + // Do first rotation for root, + // second rotation is done after else + root = rightRotate(root); + } + else if (root.left.key < key) // Zig-Zag (Left Right) + { + // First recursively bring + // the key as root of left-right + root.left.right = splay(root.left.right, key); + + // Do first rotation for root.left + if (root.left.right != null) + root.left = leftRotate(root.left); + } + + // Do second rotation for root + return (root.left == null) ? + root : rightRotate(root); + } + else // Key lies in right subtree + { + // Key is not in tree, we are done + if (root.right == null) return root; + + // Zag-Zig (Right Left) + if (root.right.key > key) + { + // Bring the key as root of right-left + root.right.left = splay(root.right.left, key); + + // Do first rotation for root.right + if (root.right.left != null) + root.right = rightRotate(root.right); + } + else if (root.right.key < key)// Zag-Zag (Right Right) + { + // Bring the key as root of + // right-right and do first rotation + root.right.right = splay(root.right.right, key); + root = leftRotate(root); + } + + // Do second rotation for root + return (root.right == null) ? + root : leftRotate(root); + } +} + +// The search function for Splay tree. +// Note that this function returns the +// new root of Splay Tree. If key is +// present in tree then, it is moved to root. +static node search(node root, int key) +{ + return splay(root, key); +} + +// A utility function to print +// preorder traversal of the tree. +// The function also prints height of every node +static void preOrder(node root) +{ + if (root != null) + { + System.out.print(root.key + " "); + preOrder(root.left); + preOrder(root.right); + } +} + +// Driver code +public static void main(String[] args) +{ + node root = newNode(100); + root.left = newNode(50); + root.right = newNode(200); + root.left.left = newNode(40); + root.left.left.left = newNode(30); + root.left.left.left.left = newNode(20); + + root = search(root, 20); + System.out.print("Preorder traversal of the" + + " modified Splay tree is \n"); + preOrder(root); +} +} + +// This code is contributed by 29AjayKumar diff --git a/Tree/TopView_binary_tree.cpp b/Tree/TopView_binary_tree.cpp new file mode 100644 index 000000000..aecf97699 --- /dev/null +++ b/Tree/TopView_binary_tree.cpp @@ -0,0 +1,91 @@ +#include +using namespace std; + +struct Node +{ + Node * left; + Node* right; + int hd; + int data; +}; + +Node* newNode(int key) +{ + Node* node=new Node(); + node->left = node->right = NULL; + node->data=key; + return node; +} + +void topview(Node* root) +{ + if(root==NULL) + return; + queueqa; + map mp; + int hd=0; + root->hd=hd; + + qa.push(root); + + cout<< "The top view of the tree - "; + + while(qa.size()) + { + hd=root->hd; + + // count function returns 1 if the container + // contains an element whose key is equivalent + // to hd, or returns zero otherwise. + if(mp.count(hd)==0) + mp[hd]=root->data; + if(root->left) + { + root->left->hd=hd-1; + qa.push(root->left); + } + if(root->right) + { + root->right->hd=hd+1; + qa.push(root->right); + } + qa.pop(); + root=qa.front(); + + } + + + + for(auto i=mp.begin();i!=mp.end();i++) + { + cout<second<<" "; + } + +} + +// Driver Program to test above functions +int main() +{ + /* + Create following Binary Tree + 1 + / \ + 22 333 + \ + 4444 + \ + 55555 + \ + 666666 + + */ + Node* root = newNode(1); + root->left = newNode(22); + root->right = newNode(333); + root->left->right = newNode(4444); + root->left->right->right = newNode(55555); + root->left->right->right->right = newNode(666666); + cout<<"Following are nodes in top view of the given binary tree "; + topview(root); + return 0; +} \ No newline at end of file diff --git a/Tree/Traverals/CPP/inOrder.cpp b/Tree/Traverals/CPP/inOrder.cpp new file mode 100644 index 000000000..d3b456d7b --- /dev/null +++ b/Tree/Traverals/CPP/inOrder.cpp @@ -0,0 +1,39 @@ +#include +#include +using namespace std; + +struct Node{ + //This is the structure of the binary tree. + int data; + Node *left; + Node *right; +}; + +void inOrder(Node *root) +{ + if(root!=NULL) + { + inOrder(root->left); + cout << root->data << " "; + inOrder(root->right); + } +} + + +int main(int argc, char const *argv[]) +{ + // Initializing a binary tree. + Node *root = new Node(); + root->data = 10; + root->right = new Node(); + root->right->data = 15; + root->left = new Node(); + root->left->data = 5; + root->left->left = new Node(); + root->left->left->data = 30; + root->left->right = new Node(); + root->left->right->data = 50; + + inOrder(root); + return 0; +} \ No newline at end of file diff --git a/Tree/Traverals/CPP/levelOrder.cpp b/Tree/Traverals/CPP/levelOrder.cpp new file mode 100644 index 000000000..b0acb9822 --- /dev/null +++ b/Tree/Traverals/CPP/levelOrder.cpp @@ -0,0 +1,46 @@ +#include +#include +using namespace std; + +struct Node{ + //This is the structure of the binary tree. + int data; + Node *left; + Node *right; +}; + +void levelOrderTraversal(Node *root) +{ + queue q; + q.push(root); + while(!q.empty()){ + root = q.front(); + q.pop(); + cout << root->data << " "; + + if(root->left!=NULL){ + q.push(root->left); + } + if(root->right!=NULL){ + q.push(root->right); + } + } +} + +int main(int argc, char const *argv[]) +{ + // Initializing a 3 element binary tree. + Node *root = new Node(); + root->data = 10; + root->right = new Node(); + root->right->data = 15; + root->left = new Node(); + root->left->data = 5; + root->left->left = new Node(); + root->left->left->data = 30; + root->left->right = new Node(); + root->left->right->data = 50; + + levelOrderTraversal(root); + return 0; +} \ No newline at end of file diff --git a/Tree/Traverals/CPP/postOrder.cpp b/Tree/Traverals/CPP/postOrder.cpp new file mode 100644 index 000000000..cc972d955 --- /dev/null +++ b/Tree/Traverals/CPP/postOrder.cpp @@ -0,0 +1,39 @@ +#include +#include +using namespace std; + +struct Node{ + //This is the structure of the binary tree. + int data; + Node *left; + Node *right; +}; + +void postOrder(Node *root) +{ + if(root!=NULL) + { + postOrder(root->left); + postOrder(root->right); + cout << root->data << " "; + } +} + + +int main(int argc, char const *argv[]) +{ + // Initializing a 3 element binary tree. + Node *root = new Node(); + root->data = 10; + root->right = new Node(); + root->right->data = 15; + root->left = new Node(); + root->left->data = 5; + root->left->left = new Node(); + root->left->left->data = 30; + root->left->right = new Node(); + root->left->right->data = 50;; + + postOrder(root); + return 0; +} \ No newline at end of file diff --git a/Tree/Traverals/CPP/preOrder.cpp b/Tree/Traverals/CPP/preOrder.cpp new file mode 100644 index 000000000..bfdd63e21 --- /dev/null +++ b/Tree/Traverals/CPP/preOrder.cpp @@ -0,0 +1,39 @@ +#include +#include +using namespace std; + +struct Node{ + //This is the structure of the binary tree. + int data; + Node *left; + Node *right; +}; + +void preOrder(Node *root) +{ + if(root!=NULL) + { + cout << root->data << " "; + preOrder(root->left); + preOrder(root->right); + } +} + + +int main(int argc, char const *argv[]) +{ + // Initializing a 3 element binary tree. + Node *root = new Node(); + root->data = 10; + root->right = new Node(); + root->right->data = 15; + root->left = new Node(); + root->left->data = 5; + root->left->left = new Node(); + root->left->left->data = 30; + root->left->right = new Node(); + root->left->right->data = 50; + + preOrder(root); + return 0; +} \ No newline at end of file diff --git a/Tree/Traverals/JAVA/BinaryTree.java b/Tree/Traverals/JAVA/BinaryTree.java new file mode 100644 index 000000000..5d9d20a50 --- /dev/null +++ b/Tree/Traverals/JAVA/BinaryTree.java @@ -0,0 +1,36 @@ +import java.io.*; + +public class BinaryTree{ + + private TreeNode root; + private class TreeNode{ + + private TreeNode right; + private TreeNode left; + private int data; //genric we can store any data + public TreeNode(int data){ + this.data = data; + System.out.println(data); + } + } + public void createBinaryTree(){ + + TreeNode first = new TreeNode(1); + TreeNode second = new TreeNode(2); + TreeNode third = new TreeNode(3); + TreeNode fourth = new TreeNode(4); + TreeNode fifth = new TreeNode(5); + + root = first; + first.left = second; + first.right = third; + second.left = fourth; + second.right = fifth; + + + } + public static void main(String args[]){ + BinaryTree obj = new BinaryTree(); + obj.createBinaryTree(); + } +} \ No newline at end of file diff --git a/Tree/Traverals/JAVA/inorder.java b/Tree/Traverals/JAVA/inorder.java new file mode 100644 index 000000000..b09d56c81 --- /dev/null +++ b/Tree/Traverals/JAVA/inorder.java @@ -0,0 +1,74 @@ +/*when you are compiling your program change the .java class file to inorder because the class declared as public*/ + +import java.io.*; +import java.util.*; + public class inorder{ + + private Node root; + private class Node{ + + private Node left; + private Node right; + int data; + public Node(int data){ + this.data=data; + System.out.print(data+"\t"); + } + } + + public void createBinaryTree(){ + + Node first = new Node(1); + Node second = new Node(2); + Node third = new Node(3); + Node fourth = new Node(4); + Node fifth = new Node(5); + + root = first; + first.left = second; + first.right = third; + second.left = fourth; + second.right = fifth; + } + + /* public void inorders(Node root){ + + if(root == null){ + return ; + } + inorders(root.left); + System.out.print(root.data+"\t"); + inorders(root.right); + } */ + +/* this is using the stack concept*/ + + public void inorders(){ + + if(root == null){ + return; + } + Stack stack = new Stack<>(); + Node temp = root; + while(!stack.isEmpty() || (temp!=null)){ + if(temp!=null){ + stack.push(temp); + temp = temp.left; + }else{ + temp = stack.pop(); + System.out.print(temp.data+"\t"); + temp = temp.right; + } + } +} + + public static void main(String args[]){ + + inorder obj = new inorder(); + System.out.println("Before inorder"); + obj.createBinaryTree(); + System.out.println(); + System.out.println("After inorder"); + obj.inorders(); + } +} \ No newline at end of file diff --git a/Tree/Traverals/JAVA/postorder.java b/Tree/Traverals/JAVA/postorder.java new file mode 100644 index 000000000..52b51919e --- /dev/null +++ b/Tree/Traverals/JAVA/postorder.java @@ -0,0 +1,56 @@ +import java.io.*; +import java.util.*; + + class postorder{ + private Node root; + private class Node{ + + private Node left; + private Node right; + + int data; + + public Node(int data){ + this.data=data; + System.out.print(data+"\t"); + } + } + + public void createBinaryTree(){ + + + Node first = new Node(1); + Node second = new Node(2); + Node third = new Node(3); + Node fourth = new Node(4); + Node fifth = new Node(5); + + root = first; + first.left = second; + first.right = third; + second.left = fourth; + second.right = fifth; + } + + public void postorders(Node root){ + + if(root == null){ + return ; + } + postorders(root.left); + postorders(root.right); + System.out.print(root.data+"\t"); + } + + + + public static void main(String args[]){ + + postorder obj = new postorder(); + System.out.println("Before post"); + obj.createBinaryTree(); + System.out.println(); + System.out.println("After postorder"); + obj.postorders(obj.root); + } +} diff --git a/Tree/Traverals/JAVA/preorder.java b/Tree/Traverals/JAVA/preorder.java new file mode 100644 index 000000000..716237b73 --- /dev/null +++ b/Tree/Traverals/JAVA/preorder.java @@ -0,0 +1,69 @@ +import java.io.*; +import java.util.*; + + public class preorder{ + private Node root; + private class Node{ + int data; + private Node right; + private Node left; + + private Node(int data){ + this.data = data; + System.out.print(data+"\t"); + } +} + public void createBinaryTree(){ + + Node first = new Node(1); + Node second = new Node(2); + Node third = new Node(3); + Node fourth = new Node(4); + Node fifth = new Node(5); + + root = first; + first.left = second; + first.right = third; + second.left = fourth; + second.right = fifth; + } +/* public void preorders(Node root){ + if(root == null){ + return ; + } + System.out.print(root.data+"\t"); + preorders(root.left); + preorders(root.right); + } */ + + public void preorders(){ + + if(root == null){ + return; + } + Stack stack = new Stack<>(); + stack.push(root); + + while(!stack.isEmpty()){ + + Node temp = stack.pop(); + System.out.print(temp.data+"\t"); + if(temp.right!= null){ + stack.push(temp.right); + } + if(temp.left!=null){ + stack.push(temp.left); + } + } + +} + + public static void main(String args[]){ + preorder obj = new preorder(); + System.out.println("Before preorders"); + obj.createBinaryTree(); + System.out.println(); + System.out.println("After preorders"); + obj.preorders(); + } +} diff --git a/Tree/right_view_binary_tree/cpp/right_view_binary_tree.cpp b/Tree/right_view_binary_tree/cpp/right_view_binary_tree.cpp new file mode 100644 index 000000000..e8f540aca --- /dev/null +++ b/Tree/right_view_binary_tree/cpp/right_view_binary_tree.cpp @@ -0,0 +1,56 @@ +#include +using namespace std; +struct node +{ + int d; + node *left; + node *right; +}; + +struct node* newnode(int num) +{ + node *temp=new node; + temp->d=num; + temp->left=temp->right=NULL; + return temp; +} + +void rightview(struct node *root, int level, int *maxlevel) +{ + if(root==NULL) + return; + + + if(*maxleveld<<" "; + *maxlevel=level; + } + + rightview(root->right,level+1,maxlevel); + rightview(root->left,level+1,maxlevel); + +} + +int main() +{ + struct node *root = newnode(1); + root->left = newnode(2); + root->right = newnode(3); + root->left->left = newnode(4); + root->left->right = newnode(5); + root->right->left = newnode(6); + root->right->right = newnode(7); + root->right->left->right = newnode(8); + + + int maxlevel=0; + + cout<<"\nRight view : "; + rightview(root,1,&maxlevel); + + cout< 0; --i) t[i] = t[i<<1] + t[i<<1|1]; +} + +void modify(int p, int value) { // set value at position p + for (t[p += n] = value; p > 1; p >>= 1) t[p>>1] = t[p] + t[p^1]; +} + +int query(int l, int r) { // sum on interval [l, r) + int res = 0; + for (l += n, r += n; l < r; l >>= 1, r >>= 1) { + if (l&1) res += t[l++]; + if (r&1) res += t[--r]; + } + return res; +} + +int main() { + scanf("%d", &n); + for (int i = 0; i < n; ++i) scanf("%d", t + n + i); + build(); + modify(0, 1); + printf("%d\n", query(3, 11)); + return 0; +} \ No newline at end of file diff --git a/Tree/segment tree/cpp/Inversion Count Segment tree.cpp b/Tree/segment tree/cpp/Inversion Count Segment tree.cpp new file mode 100644 index 000000000..b3738cc39 --- /dev/null +++ b/Tree/segment tree/cpp/Inversion Count Segment tree.cpp @@ -0,0 +1,56 @@ +#include +using namespace std; +typedef long long int ll; +ll tree[800001],n,sum; +struct nud{ + ll val,id; +}a[200001]; +bool cmp(nud n1,nud n2) +{ + if(n1.val==n2.val) + return n1.id>n2.id; + return n1.val>n2.val; +} +void query(ll node,ll l,ll r,ll pos) +{ + if(l==r) + { + tree[node]++; + return; + } + ll mid=(l+r)/2; + if(pos<=mid) + { + query(2*node,l,mid,pos); + } + else{ + sum+=tree[2*node]; + query(2*node+1,mid+1,r,pos); + } + tree[node]=tree[2*node]+tree[2*node+1]; +} +int main() { + // your code goes here + ll t; + cin>>t; + while(t--) + { + ll n; + cin>>n; + ll i,j,k=0; + sum=0; + memset(tree,0,sizeof(tree)); + for(i=1;i<=n;i++) + { + cin>>a[i].val; + a[i].id=i; + } + sort(a+1,a+n+1,cmp); + for(i=1;i<=n;i++) + { + query(1,1,n,a[i].id); + } + cout< +using namespace std; +typedef long long int ll; +ll tree[400001],tree1[400001]; +void lazy(ll node,ll l,ll r) +{ + tree[node]+=tree1[node]*(r-l+1); + if(l==r) + { + tree1[node]=0; + return; + } + tree1[2*node]+=tree1[node]; + tree1[2*node+1]+=tree1[node]; + tree1[node]=0; +} +ll q0(ll node,ll l,ll r,ll l1,ll r1,ll val=0){ + //cout<>t; + while(t--) + { + ll n,m; + cin>>n>>m; + ll i,j,k; + memset(tree,0,sizeof(tree)); + memset(tree1,0,sizeof(tree1)); + while(m--) + { + ll x,p,q,v; + cin>>x; + if(x==0) + { + cin>>p>>q>>v; + q0(1,1,n,p,q,v); + } + else{ + cin>>p>>q; + cout< +#include +#include +using namespace std; + +// Structure of binary tree +struct Node +{ + Node * left; + Node* right; + int hd; + int data; +}; + +// function to create a new node +Node* newNode(int key) +{ + Node* node=new Node(); + node->left = node->right = NULL; + node->data=key; + return node; +} + +// function should print the topView of +// the binary tree +void topview(Node* root) +{ + if(root==NULL) + return; + queueq; + map m; + int hd=0; + root->hd=hd; + + // push node and horizontal distance to queue + q.push(root); + + cout<< "The top view of the tree is : \n"; + + while(q.size()) + { + hd=root->hd; + + // count function returns 1 if the container + // contains an element whose key is equivalent + // to hd, or returns zero otherwise. + if(m.count(hd)==0) + m[hd]=root->data; + if(root->left) + { + root->left->hd=hd-1; + q.push(root->left); + } + if(root->right) + { + root->right->hd=hd+1; + q.push(root->right); + } + q.pop(); + root=q.front(); + + } + + + + for(auto i=m.begin();i!=m.end();i++) + { + cout<second<<" "; + } + +} + +// Driver Program to test above functions +int main() +{ + /* Create following Binary Tree + 1 + / \ + 2 3 + \ + 4 + \ + 5 + \ + 6*/ + Node* root = newNode(1); + root->left = newNode(2); + root->right = newNode(3); + root->left->right = newNode(4); + root->left->right->right = newNode(5); + root->left->right->right->right = newNode(6); + cout<<"Following are nodes in top view of Binary Tree\n"; + topview(root); + return 0; +} \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..2f7efbeab --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-minimal \ No newline at end of file diff --git a/data structures/Bloom Filter/bloomfilter.go b/data structures/Bloom Filter/bloomfilter.go new file mode 100644 index 000000000..6bfbcaf87 --- /dev/null +++ b/data structures/Bloom Filter/bloomfilter.go @@ -0,0 +1,103 @@ +package probabilistic + +/** +* Usage: +* bloom := NewBloomFilter(50, 3) +* bloom.Add("foo") +* bloom.MightContain("foo") +* bloom.MightContain("bar") +* bloom.CalculateFPP() +**/ + +import ( + "bytes" + "encoding/gob" + "math" + + "github.com/spaolacci/murmur3" + "github.com/willf/bitset" +) + +type BloomFilter struct { + capacity int + hashCount int + keySize int + bits bitset.BitSet +} + +/** +The Add function will hash the key for multiple hash functions and +set the corresponding bit to 1. +*/ +func (filter *BloomFilter) Add(key interface{}) { + indexes := filter.getIndexes(key) + + for i := 0; i < len(indexes); i++ { + filter.bits.Set(indexes[i]) + } + + filter.keySize += 1 +} + +/** +The MightContain function will verify is an element was possibly added. May +return false positives but never false negatives. +*/ +func (filter *BloomFilter) MightContain(key interface{}) bool { + indexes := filter.getIndexes(key) + + for i := 0; i < len(indexes); i++ { + found := filter.bits.Test(indexes[i]) + if !found { + return false + } + } + + return true +} + +/** +Calculate the expected false positive probability. +*/ +func (filter *BloomFilter) CalculateFPP() float64 { + exp := float64(-filter.hashCount*filter.keySize) / float64(filter.capacity) + base := math.Pow(math.E, exp) + return math.Pow(float64(1-base), float64(filter.hashCount)) +} + +/** +Generate the hashes from the key. Please refer to Less Hashing, Same Performance: +Building a Better Bloom Filter (Adam Kirsch, Michael Mitzenmacher) that proves +how it is possible create the multiple hashes using only 2 hash functions. +*/ +func (filter *BloomFilter) getIndexes(key interface{}) []uint { + indexes := make([]uint, filter.hashCount) + keyBytes, _ := getBytes(key) + max := uint(filter.capacity) + h1, h2 := murmur3Hash(keyBytes) + + for hashIndex := 0; hashIndex < filter.hashCount; hashIndex++ { + i := uint(hashIndex) + indexes[i] = (uint(h1) + i*uint(h2) + i*i) % max + } + + return indexes +} + +func murmur3Hash(keyBytes []byte) (uint64, uint64) { + return murmur3.Sum128(keyBytes) +} + +func getBytes(key interface{}) ([]byte, error) { + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + err := enc.Encode(key) + if err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +func NewBloomFilter(capacity int, hashCount int) *BloomFilter { + return &BloomFilter{keySize: 0, capacity: capacity, hashCount: hashCount, bits: *bitset.New(uint(capacity))} +} diff --git a/data structures/Fenwick_Tree.cpp b/data structures/Fenwick_Tree.cpp new file mode 100644 index 000000000..788719349 --- /dev/null +++ b/data structures/Fenwick_Tree.cpp @@ -0,0 +1,89 @@ +// C++ code to demonstrate operations of Binary Index Tree +#include + +using namespace std; + +/* n --> No. of elements present in input array. + BITree[0..n] --> Array that represents Binary Indexed Tree. + arr[0..n-1] --> Input array for which prefix sum is evaluated. */ + +// Returns sum of arr[0..index]. This function assumes +// that the array is preprocessed and partial sums of +// array elements are stored in BITree[]. +int getSum(int BITree[], int index) +{ + int sum = 0; // Iniialize result + + // index in BITree[] is 1 more than the index in arr[] + index = index + 1; + + // Traverse ancestors of BITree[index] + while (index>0) + { + // Add current element of BITree to sum + sum += BITree[index]; + + // Move index to parent node in getSum View + index -= index & (-index); + } + return sum; +} + +// Updates a node in Binary Index Tree (BITree) at given index +// in BITree. The given value 'val' is added to BITree[i] and +// all of its ancestors in tree. +void updateBIT(int BITree[], int n, int index, int val) +{ + // index in BITree[] is 1 more than the index in arr[] + index = index + 1; + + // Traverse all ancestors and add 'val' + while (index <= n) + { + // Add 'val' to current node of BI Tree + BITree[index] += val; + + // Update index to that of parent in update View + index += index & (-index); + } +} + +// Constructs and returns a Binary Indexed Tree for given +// array of size n. +int *constructBITree(int arr[], int n) +{ + // Create and initialize BITree[] as 0 + int *BITree = new int[n+1]; + for (int i=1; i<=n; i++) + BITree[i] = 0; + + // Store the actual values in BITree[] using update() + for (int i=0; i0): + vertex = queue.pop(0) + if(vertex not in visited): + visited.append(vertex) + currentNode = self.graph[vertex-1] + while(currentNode!=None): + if(currentNode.vertex==vertexTo): + return True + queue.append(currentNode.vertex) + currentNode = currentNode.next + return False + def isVertex(self,vertex): + return vertex in self.graphItems + def __str__(self): + return self.printGraph("key") + def printGraph(self,gtype=None): + out = "" + for i in range(len(self.graph)): + paths = "" + node = self.graph[i] + while(node!=None): + if(gtype=="key"): + paths += "-->"+str(node.vertex) + else: + paths += "-->"+str(self.graphItems[node.vertex-1]) + node = node.next + if(gtype=="key"): + out += "V"+str(i+1)+" :"+paths+"\n" + else: + out += str(self.graphItems[i])+" :"+paths+"\n" + return out +graph = Graph() +while(True): + userInput = str(input()) + if(userInput=="END"): + break + vertexFrom = userInput.split()[0] + vertexTo = userInput.split()[1] + #Creating the vertexes if vertexes are not already created + if(not graph.isVertex(vertexFrom)): + graph.addVertex(vertexFrom) + if(not graph.isVertex(vertexTo)): + graph.addVertex(vertexTo) + graph.addEdge(vertexFrom,vertexTo) +print(graph) diff --git a/data structures/Graph/GraphAL.py b/data structures/Graph/GraphAL.py new file mode 100644 index 000000000..50788a304 --- /dev/null +++ b/data structures/Graph/GraphAL.py @@ -0,0 +1,77 @@ +class Node: + def __init__(self,vertex): + self.vertex = vertex + self.next = None + def getEndNode(self): + nextNode = self + returnNode = self + while(nextNode!=None): + returnNode = nextNode + nextNode = nextNode.next + return returnNode +class Graph: + def __init__(self): + self.graphItems = [] #graph vertexes + self.graph = [] #graph with nodes + self.edges = [] + def addVertex(self,data): + self.graphItems.append(data) + self.graph.append(None) + def getVertexNumber(self,value): + return self.graphItems.index(value)+1 + def addEdge(self,vertexFrom,vertexTo): + vertexFrom = self.getVertexNumber(vertexFrom) + vertexTo = self.getVertexNumber(vertexTo) + fromNode = self.graph[vertexFrom-1] + node = Node(vertexTo) + if(fromNode!=None): #check whether there is a path added to the fromeNode position if not, node will be the first path + endNode = fromNode.getEndNode() + endNode.next = node + else: + self.graph[vertexFrom-1] = node + def isEdge(self,vertexFrom,vertexTo): + vertexFrom = self.getVertexNumber(vertexFrom) + vertexTo = self.getVertexNumber(vertexTo) + currentPos = self.graph[vertexFrom-1] + while(currentPos!=None): + if(currentPos.vertex==vertexTo): + return True + currentPos = currentPos.next + return False + def isPath(self,vertexFrom,vertexTo): + vertexFrom = self.getVertexNumber(vertexFrom) + vertexTo = self.getVertexNumber(vertexTo) + visited = [] + queue = [] + queue.append(vertexFrom) + while(len(queue)>0): + vertex = queue.pop(0) + if(vertex not in visited): + visited.append(vertex) + currentNode = self.graph[vertex-1] + while(currentNode!=None): + if(currentNode.vertex==vertexTo): + return True + queue.append(currentNode.vertex) + currentNode = currentNode.next + return False + def isVertex(self,vertex): + return vertex in self.graphItems + def __str__(self): + return self.printGraph("key") + def printGraph(self,gtype=None): + out = "" + for i in range(len(self.graph)): + paths = "" + node = self.graph[i] + while(node!=None): + if(gtype=="key"): + paths += "-->"+str(node.vertex) + else: + paths += "-->"+str(self.graphItems[node.vertex-1]) + node = node.next + if(gtype=="key"): + out += "V"+str(i+1)+" :"+paths+"\n" + else: + out += str(self.graphItems[i])+" :"+paths+"\n" + return out diff --git a/data structures/Graph/GraphBFS.py b/data structures/Graph/GraphBFS.py new file mode 100644 index 000000000..165192067 --- /dev/null +++ b/data structures/Graph/GraphBFS.py @@ -0,0 +1,70 @@ +class Node: + def __init__(self,vertex): + self.vertex = vertex + self.next = None + +userinput = str(input("Number of nodes and edges : ")).split() #First line as a string and split (from spaces) it to an array. +N = int(userinput[0]) #Extract Number of vertexes +M = int(userinput[1]) #Extract Number of edges + +graph = [] #Create an array to hold the graph +for i in range(N): + graph.append(None) + +#Requesting next M lines of inputs which are the description of edges +for i in range(M): + edges = str(input("Edge if between vertexes : ")).split() #string input line of the user splitted in to an array + fromVertex = int(edges[0]) #extracting the 1st vertex of the user input and assigning it to fromVertex + toVertex = int(edges[1])#extracting the 2nd vertex of the user input and assigning it to toVertex + + #Now let us create a node to toVertex and put that it to a/the linkedlist in the postion of fromVertex in the main graph + node = Node(toVertex) #creating the node + #if there's no linkedlist already in that position, then put the node there + if(graph[fromVertex-1]== None): + graph[fromVertex-1] = node + else: + #if there's already a linkedlist append the linkedlist to the newly created node and put that in to the position of fromNode in the main graph + node.next = graph[fromVertex-1] + graph[fromVertex-1] = node + +def bfs(graph,source): + color = [] + distance = [] + for i in range(len(graph)): + color.append("white") + distance.append(None) + color[source-1] = "gray" + distance[source-1] = 0 + Queue = [] + Queue.append(source) + while(len(Queue)!=0): + u = Queue.pop(0) + node = graph[u-1] + while(node!=None): + if(color[node.vertex-1]=="white"): + Queue.append(node.vertex) + color[node.vertex-1]="gray" + distance[node.vertex-1] = distance[u-1]+1 + node = node.next + color[u-1] = "black" + return distance + +#Now let us see how we can use this BFS +#If you want to print distances from 3 to other vertexes, call bfs function with the source vertex 3. +print(bfs(graph,3)) + + + + + + + + + + + + + + + + diff --git a/data structures/Graph/GraphDFS(Letters).py b/data structures/Graph/GraphDFS(Letters).py new file mode 100644 index 000000000..58552e81e --- /dev/null +++ b/data structures/Graph/GraphDFS(Letters).py @@ -0,0 +1,116 @@ +class Node: + def __init__(self,vertex): + self.vertex = vertex + self.next = None + def __repr__(self): + out = "" + tn = self + while(tn!=None): + out += str(tn.vertex)+"->" + tn = tn.next + return out[0:len(out)-2] +class Stack: + def __init__(self): + self.stack = [] + def push(self,data): + self.stack.append(data) + def pop(self): + return self.stack.pop() + def peek(self): + return self.stack[len(self.stack)-1] + def isEmpty(self): + return len(self.stack)==0 + +vertexdata = [] +#all the vertex UIs should go through this function +def getVertex(vertexData): + global vertexdata + #returns the position of graph + + return vertexdata.index(vertexData)#int(vertexData)-1 +def getVertexData(vertex): + global vertexdata + return vertexdata[vertex] +def makeData(amount): + global vertexdata + vertexdata = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")[0:amount] +userinput = str(input()).split() +N = int(userinput[0]) +M = int(userinput[1]) + +graph = [] +makeData(N) +for i in range(N): + graph.append(None) + +for i in range(M): + edges = str(input()).split() + fromVertex = edges[0] #fromVertex is UI + toVertex = edges[1] #toVertex is UI + node = Node(getVertex(toVertex)) + if(graph[getVertex(fromVertex)]== None): + graph[getVertex(fromVertex)] = node + else: + node.next = graph[getVertex(fromVertex)] + graph[getVertex(fromVertex)] = node + #since undirected + node = Node(getVertex(fromVertex)) + if(graph[getVertex(toVertex)]== None): + graph[getVertex(toVertex)] = node + else: + node.next = graph[getVertex(toVertex)] + graph[getVertex(toVertex)] = node + +def dfs(graph,start): #source is UI + global vertexdata + order = [] + time = 0 #time count + dTime = [] #discover times + fTime = [] #final times + predecessor = [] + + visited = Stack() + + colors = ["White" for i in range(len(graph))] + dTime = [None for i in range(len(graph))] + fTime = [None for i in range(len(graph))] + predecessor = [None for i in range(len(graph))] + + sources = list(range(len(graph))) + start = sources.pop(getVertex(start)) + sources = [start]+sources + for source in sources: + if(colors[source]=="White"): + time+=1 + colors[source] = "Gray" + dTime[source] = time + visited.push(source) + while(not visited.isEmpty()): + current = visited.peek() + adjecents = [] + adjList = graph[current] + tempNode = adjList + while(tempNode!=None): + adjecents.append(tempNode.vertex) + tempNode = tempNode.next + adjecents.sort() + currentVertex = None + for i in range(len(adjecents)): + if(colors[adjecents[i]]=="White"): + time +=1 + currentVertex = adjecents[i] + colors[adjecents[i]]="Gray" + dTime[adjecents[i]]=time + predecessor[adjecents[i]] = current + break + if(currentVertex==None): + time +=1 + vertex = visited.pop() + colors[vertex]="Black" + dTime[vertex]=time + order.append(vertexdata[vertex]) + else: + visited.push(currentVertex) + return order + +print(dfs(graph,"A")) diff --git a/data structures/Graph/GraphDFS.py b/data structures/Graph/GraphDFS.py new file mode 100644 index 000000000..d6f39d1d7 --- /dev/null +++ b/data structures/Graph/GraphDFS.py @@ -0,0 +1,106 @@ +class Node: + def __init__(self,vertex): + self.vertex = vertex + self.next = None + def __repr__(self): + out = "" + tn = self + while(tn!=None): + out += str(tn.vertex)+"->" + tn = tn.next + return out[0:len(out)-2] +class Stack: + def __init__(self): + self.stack = [] + def push(self,data): + self.stack.append(data) + def pop(self): + return self.stack.pop() + def peek(self): + return self.stack[len(self.stack)-1] + def isEmpty(self): + return len(self.stack)==0 + +#all the vertex UIs should go through this function +def getVertex(vertexData): + return int(vertexData)-1 + +userinput = str(input()).split() +N = int(userinput[0]) +M = int(userinput[1]) + +graph = [] +for i in range(N): + graph.append(None) + +for i in range(M): + edges = str(input()).split() + fromVertex = edges[0] #fromVertex is UI + toVertex = edges[1] #toVertex is UI + node = Node(getVertex(toVertex)) + if(graph[getVertex(fromVertex)]== None): + graph[getVertex(fromVertex)] = node + else: + node.next = graph[getVertex(fromVertex)] + graph[getVertex(fromVertex)] = node + #since undirected + node = Node(getVertex(fromVertex)) + if(graph[getVertex(toVertex)]== None): + graph[getVertex(toVertex)] = node + else: + node.next = graph[getVertex(toVertex)] + graph[getVertex(toVertex)] = node + +def dfs(graph,start): #source is UI + global vertexdata + order = [] + time = 0 #time count + dTime = [] #discover times + fTime = [] #final times + predecessor = [] + + visited = Stack() + + colors = ["White" for i in range(len(graph))] + dTime = [None for i in range(len(graph))] + fTime = [None for i in range(len(graph))] + predecessor = [None for i in range(len(graph))] + + sources = list(range(len(graph))) + start = sources.pop(getVertex(start)) + sources = [start]+sources + for source in sources: + if(colors[source]=="White"): + time+=1 + colors[source] = "Gray" + dTime[source] = time + visited.push(source) + while(not visited.isEmpty()): + current = visited.peek() + adjecents = [] + adjList = graph[current] + tempNode = adjList + while(tempNode!=None): + adjecents.append(tempNode.vertex) + tempNode = tempNode.next + adjecents.sort() + currentVertex = None + for i in range(len(adjecents)): + if(colors[adjecents[i]]=="White"): + time +=1 + currentVertex = adjecents[i] + colors[adjecents[i]]="Gray" + dTime[adjecents[i]]=time + predecessor[adjecents[i]] = current + break + if(currentVertex==None): + time +=1 + vertex = visited.pop() + colors[vertex]="Black" + dTime[vertex]=time + order.append(vertexdata[vertex]) + else: + visited.push(currentVertex) + return order + +print(dfs(graph,"A")) diff --git a/data structures/Graph/GraphDictionaries.py b/data structures/Graph/GraphDictionaries.py new file mode 100644 index 000000000..a97140517 --- /dev/null +++ b/data structures/Graph/GraphDictionaries.py @@ -0,0 +1,157 @@ +class Graph(object): + def __init__(self,graph={}): + self.graph=graph + + def vertices(self): + return list(self.graph.keys()) + + def isVertex(self,vertex): + vert=self.vertices() + if vertex in vert: + return True + else: + return False + + + def edges(self): + return self.generateEdges() + + def isEdge(self,vertexFrom,vertexTo): + edgesOfGraph=self.edges() + if (vertexFrom,vertexTo) in edgesOfGraph: + return True + else: + return False + + def addVertex(self,vertex): + if vertex not in self.graph: + self.graph[vertex]=[] + + def addEdge(self,edge): + edge=set(edge) + (vertex1,vertex2)=tuple(edge) + if vertex1 in self.graph: + self.graph[vertex1].append(vertex2) + else: + self.graph[vertex1]=[vertex2] + + def generateEdges(self): + edges=[] + for vertex in self.graph: + for neighbour in self.graph[vertex]: + if (neighbour,vertex) not in edges: + edges.append((vertex,neighbour)) + return edges + + def printGraph(self): + res="Vertices : " + for k in self.graph: + res+=str(k)+" " + res+="\nedges :" + for edge in self.generateEdges(): + res+=str(edge)+" " + return res + + def findPath(self,startVertex,endVertex,path=[]): + graph=self.graph + path=path+[startVertex] + if startVertex==endVertex: + return path + if startVertex not in graph: + return None + for vertex in graph[startVertex]: + if vertex not in path: + extendedPath=self.findPath(vertex,endVertex,path) + + if extendedPath: + return extendedPath + return None + + def find_all_paths(self, startVertex, endVertex, path=[]): + + graph = self.graph + path = path + [startVertex] + if startVertex == endVertex: + return [path] + if startVertex not in graph: + return [] + paths = [] + for vertex in graph[startVertex]: + if vertex not in path: + extendedPaths = self.find_all_paths(vertex, + endVertex, + path) + for p in extendedPaths: + paths.append(p) + return paths + + def findOutDegree(self,vertex): + vert=self.vertices() + if vertex not in vert: + return None + else: + count=0 + for vrtx in self.graph: + if vrtx==vertex: + for neighbour in self.graph[vertex]: + count+=1 + return count + + def findInDegree(self,vertex): + vert=self.vertices() + if vertex not in vert: + return None + else: + count=0 + for vrtx in self.graph: + for neighbour in self.graph[vrtx]: + if neighbour==vertex: + count+=1 + return count + + + +g = { "a" : ["c"], + "b" : ["e"], + "c" : ["b", "d", "e","f"], + "d" : [], + "e" : ["f","c"], + "f" : ["b"] + } +gW = { "a":[1], + "b":[2], + "c":[] + } + +graph = Graph(g) +''' +graph.vertices() +['a', 'c', 'b', 'e', 'd', 'f'] + +graph.isEdge('b','c') +False + +graph.isEdge('c','b') +True + +graph.findPath('a','c') +['a', 'c'] + +graph.findPath('a','f') +['a', 'c', 'b', 'e', 'f'] + +graph.find_all_paths('a','f') +[['a', 'c', 'b', 'e', 'f'], ['a', 'c', 'e', 'f'], ['a', 'c', 'f']] + +graph.findInDegree('c') +2 + +graph.findOutDegree('c') +4 + +graph.findInDegree('f') +2 + +graph.findOutDegree('f') +1 + ''' diff --git a/data structures/Matrix/cpp/Array.h b/data structures/Matrix/cpp/Array.h new file mode 100644 index 000000000..e94c75b3a --- /dev/null +++ b/data structures/Matrix/cpp/Array.h @@ -0,0 +1,58 @@ +#include +#include +#include +using namespace std; + +class IndexOutOfBoundsException{}; + +template + < typename Type > +class Array +{ +private: + int len; + Type * buf; +public: + Array(int newLen) + :len( newLen ), buf( new Type [newLen] ) + { + } + Array( const Array & l) + : len( l.len ), buf( new Type [l.len] ) + { + for( int i = 0; i < l.len; i++ ) + buf[i] = l.buf[i]; // note = is incorrect if buf elements are pointers + } + int length() + { + return len; + } + Type &operator [] (int i) + throw (IndexOutOfBoundsException) + { + if (!(0 <= i && i < len)) + throw IndexOutOfBoundsException(); + return buf[i]; + } + void print(ostream & out) + { + for(int i = 0; i < len; ++i) + out << setw(8) << setprecision(2) << fixed << right << buf[i]; // #include + } + ~Array() + { + delete [] buf; + } + friend ostream & operator << ( ostream & out, Array & a ) + { + a.print( out ); + return out; + } + friend ostream & operator << (ostream & out, Array * ap) + { + ap -> print( out ); + return out; + } + // note the overloading of operator << on a pointer as wel +}; + diff --git a/data structures/Matrix/cpp/Matrix.h b/data structures/Matrix/cpp/Matrix.h new file mode 100644 index 000000000..c4aa958a7 --- /dev/null +++ b/data structures/Matrix/cpp/Matrix.h @@ -0,0 +1,52 @@ +#include "Array.h" +using namespace std; + + +template + < typename Element > +class Matrix +{ +private: + int rows, cols; + Array < Array < Element > * > m; + // define m as an Array of Array pointers using the + // template you defined above +public: + Matrix( int newRows, int newCols ) + : rows(newRows), cols (newCols), m(rows) + { + for (int i = 0; i < rows; i++) + m[i] = new Array < Element > (cols); + } + int numRows() + { + return rows; + } + int numCols() + { + return cols; + } + Array < Element > & operator [] (int row) + { + + return * m[row]; + } + void print( ostream & out) + { + for(int i = 0; i < rows; ++i) + out << m[i] << endl; + // write this one too, but use Array::operator << + } + friend ostream & operator << (ostream & out, Matrix & m) + { + m.print( out ); + return out; + } + ~Matrix() + { + for(int i = 0; i < rows; i++) + { + delete m[i]; + } + } +}; diff --git a/data structures/Matrix/cpp/main.cpp b/data structures/Matrix/cpp/main.cpp new file mode 100644 index 000000000..a028a49b5 --- /dev/null +++ b/data structures/Matrix/cpp/main.cpp @@ -0,0 +1,104 @@ +#include "Matrix.h" +#include + +template + + +void fillMatrix(Matrix &m) +{ + int i, j; + for(i=0;i < m.numRows(); i++) + m[i][0] = T(); + for(j = 0; j < m.numCols(); j++) + m[0][j] = T(); + for(i = 1; i < m.numRows(); i++) + for( j = 1; j < m.numCols(); j++) + { + m[i][j] = T(i * j); + } +} + +void test_int_matrix() +{ + cout << "Testing INT Matrix...\n" << endl; + Matrix m(10,5); + fillMatrix(m); + cout << m << "Done\n" << endl; +} + +void test_double_matrix() +{ + cout << "Testing DOUBLE Matrix...\n" << endl; + Matrix < double > M(8, 10); + fillMatrix(M); + cout << M << "Done\n" << endl; +} + +template + +void generate_exception(Matrix &m) +{ + //insert a for loop that cause the exception + cout << "Generating Exception..." << endl; + cout << "It will try to access rows 0-15 and cols 0-15\n"; + for(int i = 0; i < 15; i++) + { + for (int j = 0; j < 15; j++) + { + m[i][j]; + } + cout << endl; + } +} + +void test_double_matrix_exceptions() +{ + //PUT YOUR TRY/CATCH AROUND THE INSTRUCTIONS BELOW + try + { + cout << "Starting Double Matrix Exception...\n"; + cout << "Matrix M(8,10);\n\n"; + Matrix < double > M (8,10); + fillMatrix( M ); + cout << M; + generate_exception( M ); + } + catch ( const IndexOutOfBoundsException & e) + { + cout << "\nERROR: Index out of bounds." << endl; + } + cout << "Done\n" << endl; +} + +void test_int_matrix_exceptions() +{ + //PUT YOUR TRY/CATCH AROUND THE INSTRUCTIONS BELOW + try + { + cout << "Starting Int Matrix Exception...\n"; + cout <<"Matrix m(10,10);\n\n"; + Matrix < int > m (10,10); + fillMatrix( m ); + cout << m; + generate_exception( m ); + } + catch ( const IndexOutOfBoundsException & e) + { + cout << "\nERROR: Index out of bounds." << endl; + } + cout << "Done\n" << endl; +} + +int main() +{ + for (int i = 1; i <= 3; ++i) + { + cout << "Test " << i << "\n" << endl; + test_int_matrix(); + test_double_matrix(); + test_int_matrix_exceptions(); + test_double_matrix_exceptions(); + + } + return 0; +} diff --git a/data structures/Matrix/cpp/matrix_multiply.cpp b/data structures/Matrix/cpp/matrix_multiply.cpp new file mode 100644 index 000000000..52a01fb96 --- /dev/null +++ b/data structures/Matrix/cpp/matrix_multiply.cpp @@ -0,0 +1,41 @@ +#include +using namespace std; + +long long mod = (int)1e9 + 7; +#define matrix2D vector< vector > +matrix2D matrixMultiply(matrix2D &a, matrix2D &b) +{ + matrix2D c (a.size(), vector< long long >(b[0].size())); + for(int i=0; i(a.size())); + for(int i=0; i>=1; + } + return res; +} + +int main() +{ + matrix2D mat { {1,1},{1,0} }; + mat = matrixPower(mat, 12); + cout< { + + private Object[] array; + private int size; + + public ArrayList() { + this.array = new Object[0]; + this.size = 0; + } + + public void add(Object toAdd) { + insert(toAdd, size); + } + + public void insert(Object toAdd, int position) { + if(position > size) + position = size; + Object[] array = new Object[size + 1]; + for(int i = 0, arrayIndex = 0; i < array.length; i++, arrayIndex++) { + if(i == position) { + array[arrayIndex] = toAdd; + arrayIndex++; + } + if(i < this.array.length) + array[arrayIndex] = this.array[i]; + } + this.array = array; + this.size++; + } + + /** + * @param object the object you wish to know the index of + * @return the index of the object, or -1 if the object is not in the array + */ + public int indexOf(Object object) { + for (int i = 0; i < this.size; i++) { + if(this.array[i] == object) { + return i; + } + } + return -1; + } + + /** + * @param toDelete the object to delete + * @return the object that was deleted from the arraylist, or null if the object is not in the arraylist + */ + public Object delete(T toDelete) { + int position = -1; + for (int i = 0; i < this.size; i++) { + if(this.array[i] == toDelete) { + position = i; + break; + } + } + return delete(position); + } + + /** + * @param positionToDelete the index of the object to delete + * @return the object that was deleted from the arraylist, or null if the object is not in the arraylist + */ + public Object delete(int positionToDelete) { + Object deleted = null; + if(positionToDelete > -1) { + Object[] array = new Object[size - 1]; + for (int i = 0, arrayIndex = 0; i < this.size; i++, arrayIndex++) { + if (i == positionToDelete) { + deleted = this.array[i]; + arrayIndex--; + } + else { + array[arrayIndex] = this.array[i]; + } + } + this.array = array; + size--; + } + return deleted; + } + + public Object[] getArray() { + return array; + } + + public int size() { + return size; + } +} diff --git a/data structures/array/Array_List.cpp b/data structures/array/Array_List.cpp new file mode 100644 index 000000000..a34a312c7 --- /dev/null +++ b/data structures/array/Array_List.cpp @@ -0,0 +1,215 @@ +#include // std::size_t +#include // C++ exceptions +#include // c++ algorithms + +namespace structures { +/** Class ArrayList */ +template +class ArrayList { + public: + ArrayList(); // constructor + explicit ArrayList(std::size_t max_size); // single parameter constructor + ~ArrayList(); + void clear(); // limpa + void push_back(const T& data); // pushes a node at the end of the list + void push_front(const T& data); // pushes a node into the beginning of the list + void insert(const T& data, std::size_t index); // inserts a node at the given index + void insert_sorted(const T& data); // sorts the list and then pushes the node + T pop(std::size_t index); // remove and return node from given index + T pop_back(); // remove and return node from the back of the list + T pop_front(); // remove and return node from the beginning of the list + void remove(const T& data); // removes given data from the list + bool full(); // true if the current list is full + bool empty(); // empty if the current list is empty + bool contains(const T& data); // returns true if the list contains such data + std::size_t find(const T& data); // returns the index of given data + std::size_t size(); // returns the current size of the list + std::size_t max_size(); // returns the total size of the list + T& at(std::size_t index); // access object at given index + T& operator[](std::size_t index); // operator overloading + + private: + T* contents; + std::size_t size_; + std::size_t max_size_; + static const auto DEFAULT_MAX = 10u; +}; + +} // namespace structures + +#endif + +template +structures::ArrayList::ArrayList() { + size_= max_size_= 0; + contents= new T[max_size_]; +} + +template +structures::ArrayList::ArrayList(std::size_t max_size) { + size_= 0; + max_size_= max_size; + contents= new T[max_size_]; +} + +template +structures::ArrayList::~ArrayList() { + delete[] contents; +} + +template +void structures::ArrayList::clear() { + size_= 0; +} + +template +void structures::ArrayList::push_back(const T& data) { + if (full()) + throw std::out_of_range("LIST IS FULL!"); + contents[size_++]= data; +} + +template +void structures::ArrayList::push_front(const T& data) { + if (full()) { + throw std::out_of_range("LIST IS FULL!"); + } else { + for (int i= size_; i > 0; i--) + std::swap(contents[i], contents[i - 1]); + } + contents[0]= data; + size_++; +} + +template +void structures::ArrayList::insert(const T& data, std::size_t index) { + if (full()) { + throw std::out_of_range("LIST IS FULL!"); + } else if (index < 0 || index >= size_) { + throw std::out_of_range("INDEX OUT OF BOUNDS"); + } else { + for (int i= size_; i > index; i--) + std::swap(contents[i - 1], contents[i]); + contents[index]= data; + size_++; + } +} + +template +void structures::ArrayList::insert_sorted(const T& data) { + contents[size_++]= data; + for (int i = 0; i < size_; i++) { + for (int j = 0; j < size_; j++) { + if (contents[i] < contents[j]) + std::swap(contents[i], contents[j]); + } + } +} + +template +T structures::ArrayList::pop(std::size_t index) { + if (index < 0 || index >= size_) { + throw std::out_of_range("INDEX OUT OF BOUNDS"); + } else if (empty()) { + throw std::out_of_range("LIST IS EMPTY!"); + } else { + auto t= contents[index]; + for (int i= index; i < size_; i++) { + contents[index]= contents[index + 1]; + } + size_--; + return t; + } +} + +template +T structures::ArrayList::pop_back() { + if (empty()) + throw std::out_of_range("LIST IS EMPTY!"); + else + return contents[--size_]; +} + +template +T structures::ArrayList::pop_front() { + if (empty()) + throw std::out_of_range("LIST IS EMPTY!"); + auto t= contents[0]; + for (int i= 1; i < size_; i++) + contents[i - 1]= contents[i]; + size_--; + return t; +} + +template +void structures::ArrayList::remove(const T& data) { + int index= find(data); + if (index > -1) { + contents[index]= -1; + for (int i= index; i < size_; i++) + contents[i - 1]= 1; + size_--; + } +} + +template +bool structures::ArrayList::full() { + return size_ == max_size_; +} + +template +bool structures::ArrayList::empty() { + return size_ == 0; +} + +template +bool structures::ArrayList::contains(const T& data) { + if (empty()) { + throw std::out_of_range("LIST IS EMPTY!"); + } else { + for (int i= 0; i < size_; i++) { + if (contents[i] == data) + return true; + } + return false; + } +} + +template +std::size_t structures::ArrayList::find(const T& data) { + if (empty()) { + throw std::out_of_range("LIST IS EMPTY!"); + } else { + for (int i= 0; i < size_; i++) { + if (contents[i] == data) + return i; + } + return size_; + } +} + +template +std::size_t structures::ArrayList::size() { + return size_; +} + +template +std::size_t structures::ArrayList::max_size() { + return max_size_; +} + +template +T& structures::ArrayList::at(std::size_t index) { + if (index < 0 || index > size_ - 1) { + throw std::out_of_range("INDEX OUT OF BOUNDS"); + } else { + return contents[index]; + } +} + +template +T& structures::ArrayList::operator[](std::size_t index) { + if (empty()) + throw std::out_of_range("LIST IS EMPTY"); + return contents[index]; +} diff --git a/data structures/heap/C/heap.c b/data structures/heap/C/heap.c new file mode 100644 index 000000000..cd78c9507 --- /dev/null +++ b/data structures/heap/C/heap.c @@ -0,0 +1,61 @@ +#include "heap.h" + + + +void add(MinHeap* h, int value) { + h->heap[++(h->N)] = value; + + sift(h, h->N); + percolate(h, h->N); +} + +void rmv(MinHeap* h, int node) { + swap_nodes(h, node, h->N); + h->N--; + + sift(h, node); + percolate(h, node); +} + +void sift(MinHeap* h, int node) { + int son; + + do { + son = 0; + if(2*node+1 <= h->N) { + if (h->heap[2*node+1] < h->heap[2*node]) { + son = 2*node+1; + } else { + son = 2*node; + } + } else if (2*node <= h->N) { + son = 2*node; + } + + if(h->heap[node] < h->heap[son]) { + son = 0; + } + + if(son) { + swap_nodes(h, node, son); + node = son; + } + } while (son); +} + +void percolate(MinHeap* h, int node) { + while(node > 1 && h->heap[node] < h->heap[node/2]) { + swap_nodes(h, node, node/2); + node/=2; + } +} + +void swap_nodes(MinHeap* h, int node1, int node2) { + int man = h->heap[node1]; + h->heap[node1] = h->heap[node2]; + h->heap[node2] = man; +} + +int get_value_at_node(MinHeap* h, int node) { + return h->heap[node]; +} diff --git a/data structures/heap/C/heap.h b/data structures/heap/C/heap.h new file mode 100644 index 000000000..b87c5eeb7 --- /dev/null +++ b/data structures/heap/C/heap.h @@ -0,0 +1,26 @@ +#ifndef HEAP_H +#define HEAP_H +#define MAX_NODES 100 + + +/* An implementation of a MinHeap, a tree based data structure in which which each node's value is lesser than its children.*/ + +typedef struct +{ + int N; + int heap[MAX_NODES]; +} MinHeap; + +void add(MinHeap* h, int value); + +void rmv(MinHeap* h, int node); + +void sift(MinHeap* h, int node); + +void percolate(MinHeap* h, int node); + +void swap_nodes(MinHeap* h, int node1, int node2); + + +int get_value_at_node(MinHeap* h, int node); +#endif // HEAP_H diff --git a/data structures/kdistanceleveltraversal using java b/data structures/kdistanceleveltraversal using java new file mode 100644 index 000000000..d3104a506 --- /dev/null +++ b/data structures/kdistanceleveltraversal using java @@ -0,0 +1,169 @@ + +package kdistanceleveltraversal; + +/** + * + * @author Himanshu + */ +import java.util.Scanner; +class Node +{ + int data; + Node lc; + Node rc; + public Node(int s) + { + data=s; + } + public void displaynode() + { + System.out.print(+data+" "); + } +} +class Queue +{ + Node []queue=new Node[200]; + int front,rear; + public Queue() + { + front=-1; + rear=-1; + } + public void enque(Node l) + { + if(front==-1 && rear==-1) + { + front=0; + queue[++rear]=l; + } + else + + queue[++rear]=l; + } + public Node deque() + { + Node temp= queue[front]; + front++; + return temp; + } + public boolean isempty() + { + return(front==-1 && rear==-1); + } +} + +class Tree +{ + Node root; + + public Tree() + { + + root=null; + } + public void insert(int d) + { + Node newnode=new Node(d); + if (root==null) + root=newnode; + else + { + Node current=root; + Node parent; + while(true) + { + parent=current; + + if(current.data>d) + { + + current=current.lc; + if(current==null) + { + parent.lc=newnode; + return; + } + } + else + { + + current=current.rc; + if(current==null) + { + parent.rc=newnode; + return; + } + } + } + + + } + + } + Queue ob2=new Queue(); + int level=1; + void levelorder( Node ro,int p) + { + + ob2.enque(ro); + Node Null = null; + Node current = null; + ob2.enque(Null); + while(!ob2.isempty()) + { + + + if(level!=p+1){ + current=ob2.deque();} + else + { + break; + } + if(current!=null && level==p) + System.out.print(current.data+" "); + else if(current==null){ + level++; + ob2.enque(Null); + continue;} + if(current.lc!=null) + ob2.enque(current.lc); + if(current.rc!=null) + ob2.enque(current.rc); + if((ob2.front- ob2.rear)==1) + { + ob2.front=-1; + ob2.rear=-1; + } + + } + + } + + + +} +public class Kdistanceleveltraversal { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + // TODO code application logic here + Scanner sc=new Scanner(System.in); + System.out.print("enter how many items insert:"); + int c=sc.nextInt(); + int i,j,k,a; + Tree ob1=new Tree(); + for( i=0;i +using namespace std; +void BubbleSort(int a[], int n){ + int z,j,temp,flag; //temp will be used for swapping two consecutive numbers + for (z = 1; z a[j+1]){ + temp = a[j]; + a[j]=a[j+1]; + a[j+1]= temp; + flag = 1; + } + } + if (flag==0) //checks if sorted + break; + } + } + +int main(){ + int k; + cout << "please enter the largest element order: "; + cin >> k; + int n; + cout << "Please enter the number of array elements: "; + cin >> n; + cout <<"Please enter the array elements one number in a line: \n"; + int* a = new int[n]; // this is the line that allocates dynamically a place in memory with size n when the user enters n + for(int i=0;i> a[i]; //u can enter numbers separated by spaces or one number in each line + } + cout << "The sorted list is: \n"; + BubbleSort(a, n); + for (int i=0;i +#include +#include "list.h" + +/** +* Retourne une nouvelle Liste +* @return Une liste vide +*/ +List new_list(void) +{ + return NULL; +} + +/*---------------------------------------------------------------------*/ + +/** +* Vérifie si une List est vide +* @param li La liste à tester +* @return true si elle est vide, faux sinon +*/ +Bool is_empty_list(List li) +{ + if(li == NULL) + return true; + + return false; +} + +/*---------------------------------------------------------------------*/ + +/** +* Affiche une Liste +* @param li La liste à afficher +*/ +void print_list(List li) +{ + if(is_empty_list(li)) + { + printf("Rien a afficher, la Liste est vide.\n"); + return; + } + + while(li != NULL) + { + printf("[%d] ", li->value); + li = li->next; + } + + printf("\n"); +} + +/*---------------------------------------------------------------------*/ + +/** +* Retourne la taille de la Liste +* @param li La liste +* @return Le nombre d'élements de la Liste +*/ +int list_length(List li) +{ + int size = 0; + + if(is_empty_list(li)) + return size; + + while(li != NULL) + { + size++; + li = li->next; + } + + return size; +} + +/*---------------------------------------------------------------------*/ + +/** +* Ajoute un entier en fin de Liste +* @param li La liste +* @param x L'entier à insérer +* @return La liste avec le nouvel élement ajouté +*/ +List push_back_list(List li, int x) +{ + ListElement *element; + + element = malloc(sizeof(*element)); + + if(element == NULL) + { + fprintf(stderr, "Erreur : probleme allocation dynamique.\n"); + exit(EXIT_FAILURE); + } + + element->value = x; + element->next = NULL; + + if(is_empty_list(li)) + return element; + + ListElement *temp; + temp = li; + + while(temp->next != NULL) + temp = temp->next; + + temp->next = element; + + return li; +} + +/*---------------------------------------------------------------------*/ + +/** +* Ajoute un entier en début de Liste +* @param li La liste +* @param x L'entier à insérer +* @return La liste avec le nouvel élement ajouté +*/ +List push_front_list(List li, int x) +{ + ListElement *element; + + element = malloc(sizeof(*element)); + + if(element == NULL) + { + fprintf(stderr, "Erreur : probleme allocation dynamique.\n"); + exit(EXIT_FAILURE); + } + + element->value = x; + + if(is_empty_list(li)) + element->next = NULL; + else + element->next = li; + + return element; +} + +/*---------------------------------------------------------------------*/ + +/** +* Supprime un entier de la fin de la Liste +* @param li La liste +* @return La liste sans l'élément retiré +*/ +List pop_back_list(List li) +{ + if(is_empty_list(li)) + return new_list(); + + //Si la liste n'a qu'un seul élément + if(li->next == NULL) + { + free(li); + li = NULL; + + return new_list(); + } + + ListElement *temp = li; + ListElement *before = li; + + while(temp->next != NULL) + { + before = temp; + temp = temp->next; + } + + before->next = NULL; + + free(temp); + temp = NULL; + + return li; +} + +/*---------------------------------------------------------------------*/ + +/** +* Supprime un entier de la tête de la Liste +* @param li La liste +* @return La liste sans l'élément retiré +*/ +List pop_front_list(List li) +{ + ListElement *element; + + element = malloc(sizeof(*element)); + + if(element == NULL) + { + fprintf(stderr, "Erreur : probleme allocation dynamique.\n"); + exit(EXIT_FAILURE); + } + + if(is_empty_list(li)) + return new_list(); + + element = li->next; + + free(li); + li = NULL; + + return element; +} + +/*---------------------------------------------------------------------*/ + +/** +* Supprime tous les éléments d'une Liste +* @param li La liste +* @return Une Liste vide +*/ +List clear_list(List li) +{ + if(is_empty_list(li)) + return new_list(); + + while(li != NULL) + li = pop_front_list(li); +} diff --git a/data structures/linked list/c/liste.h b/data structures/linked list/c/liste.h new file mode 100644 index 000000000..4112b9dac --- /dev/null +++ b/data structures/linked list/c/liste.h @@ -0,0 +1,29 @@ +#ifndef __LIST__H__ +#define __LIST__H__ + + /* Définition d'un Booléen */ + typedef enum + { + false, + true + }Bool; + + /* Définition d'une Liste */ + typedef struct ListElement + { + int value; + struct ListElement *next; + }ListElement, *List; + + /* Prototypes */ + List new_list(void); + Bool is_empty_list(List li); + void print_list(List li); + int list_length(List li); + List push_back_list(List li, int x); + List push_front_list(List li, int x); + List pop_back_list(List li); + List pop_front_list(List li); + List clear_list(List li); + +#endif diff --git a/data structures/linked list/c/xor linked_list.c b/data structures/linked list/c/xor linked_list.c new file mode 100644 index 000000000..8f3240d01 --- /dev/null +++ b/data structures/linked list/c/xor linked_list.c @@ -0,0 +1,61 @@ +#include +#include +struct node +{ + int data; + struct node* npx; +}; + +struct node* XOR(struct node *a, struct node *b) +{ + return (struct node*) ((unsigned int) (a) ^ (unsigned int) (b)); +} +void insert(struct node **head_ref, int data) +{ + struct node *new_node = (struct node *) malloc(sizeof(struct node)); + new_node->data = data; + new_node->npx = XOR(*head_ref, NULL); + if (*head_ref != NULL) + { + struct node* next = XOR((*head_ref)->npx, NULL); + (*head_ref)->npx = XOR(new_node, next); + } + + // Change head + *head_ref = new_node; +} + +void printList(struct node *head) +{ + struct node *curr = head; + struct node *prev = NULL; + struct node *next; + + printf("The elements of linked list are: \n"); + + while (curr != NULL) + { + // print current node + printf("%d ", curr->data); + next = XOR(prev, curr->npx); + prev = curr; + curr = next; + } +} + +int main() +{ + int n,value; + struct node *head = NULL; + printf("Enter the number of elements you want to enter: "); + scanf("%d",&n); + printf("Enter %d elements: ",n); + while(n--) + { + scanf("%d",&value); + insert(&head,value); + } + printList(head); + + return (0); +} \ No newline at end of file diff --git a/data structures/linked list/cpp/circular_linked_list.cpp b/data structures/linked list/cpp/circular_linked_list.cpp new file mode 100644 index 000000000..46aa2bedc --- /dev/null +++ b/data structures/linked list/cpp/circular_linked_list.cpp @@ -0,0 +1,56 @@ +#include + +using namespace std; + +int main() +{ + +struct node{ + int info; + node *next; +}*ptr,*head,*start; + +int c=1,data; + +ptr=new node; +ptr->next=NULL; + +start=head=ptr; + +while(c<3 && c>0){ + cout<<"1.Insert\n2.Link List\n"; + cin>>c; + + switch(c){ + case 1: + cout<<"Enter Data\n"; + cin>>data; + + ptr=new node; + ptr->next=start; + ptr->info=data; + + head->next=ptr; + head=ptr; + + break; + + case 2: + ptr=start->next; + + while(ptr!=start && ptr!=NULL){ + cout<info<<"->"; + ptr=ptr->next; + } + cout<<"\n"; + break; + + default: + cout<<"Wrong Choice\nExiting...\n"; + } + +} + +getch(); +return 0; +} diff --git a/data structures/linked list/cpp/llMiddle.cpp b/data structures/linked list/cpp/llMiddle.cpp new file mode 100644 index 000000000..a4462a661 --- /dev/null +++ b/data structures/linked list/cpp/llMiddle.cpp @@ -0,0 +1,70 @@ +#include +#include + +/* Link list node */ +struct Node +{ + int data; + struct Node* next; +}; + +/* Function to get the middle of the linked list*/ +void printMiddle(struct Node *head) +{ + struct Node *slow_ptr = head; + struct Node *fast_ptr = head; + + if (head!=NULL) + { + while (fast_ptr != NULL && fast_ptr->next != NULL) + { + fast_ptr = fast_ptr->next->next; + slow_ptr = slow_ptr->next; + } + printf("The middle element is [%d]\n\n", slow_ptr->data); + } +} + +void push(struct Node** head_ref, int new_data) +{ + /* allocate node */ + struct Node* new_node = + (struct Node*) malloc(sizeof(struct Node)); + + /* put in the data */ + new_node->data = new_data; + + /* link the old list off the new node */ + new_node->next = (*head_ref); + + /* move the head to point to the new node */ + (*head_ref) = new_node; +} + +// A utility function to print a given linked list +void printList(struct Node *ptr) +{ + while (ptr != NULL) + { + printf("%d->", ptr->data); + ptr = ptr->next; + } + printf("NULL\n"); +} + +/* Drier program to test above function*/ +int main() +{ + /* Start with the empty list */ + struct Node* head = NULL; + int i; + + for (i=5; i>0; i--) + { + push(&head, i); + printList(head); + printMiddle(head); + } + + return 0; +} diff --git a/data structures/linked list/cpp/singly_reversed_linked_list.cpp b/data structures/linked list/cpp/singly_reversed_linked_list.cpp new file mode 100644 index 000000000..52e78112c --- /dev/null +++ b/data structures/linked list/cpp/singly_reversed_linked_list.cpp @@ -0,0 +1,57 @@ +#include +#include +using namespace std; + +struct node{ + int data; + struct node *next; +}; + +struct node *start = NULL; + +void create(int n){ + struct node *new_node, *current_node; + new_node=(struct node*)malloc(sizeof(node)); + new_node->data=n; + new_node->next=NULL; + + if(start==NULL){ + start=new_node; + current_node=new_node; + }else{ + current_node->next=new_node; + current_node=new_node; + } + +} + +void display(){ + struct node* temp=start; + while(temp!=NULL){ + cout<data<<" "; + temp=temp->next; + } +} + +void reverse_linked_list(){ + struct node *prev=NULL, *current=start, *next=NULL; + while(current!=NULL){ + next=current->next; + current->next=prev; + prev=current; + current=next; + } + start=prev; + cout<<"\n"; + display(); +} + +int main(){ + create(2); + create(27); + create(22); + create(21); + create(25); + display(); + reverse_linked_list(); +} diff --git a/data structures/linked list/cs/LinkedList/LinkedList.cs b/data structures/linked list/cs/LinkedList/LinkedList.cs new file mode 100644 index 000000000..281eef28d --- /dev/null +++ b/data structures/linked list/cs/LinkedList/LinkedList.cs @@ -0,0 +1,50 @@ +using System; + +namespace Collections { + + public class Node { + internal T Data { get; set; } + internal Node Successor { get; set; } + + internal Node (T data) { + Data = data; + } + } + + public class LinkedList { + private Node Head { get; set; } + + public T this [int index] { + get { + int i = 0; + Node current = Head; + + if (current == null) { + throw new IndexOutOfRangeException (); + } + + while (i < index) { + if (current.Successor == null) { + throw new IndexOutOfRangeException (); + } + current = current.Successor; + i++; + } + + return current.Data; + } + } + public void Append (T data) { + Node newNode = new Node (data); + if (Head == null) { + Head = newNode; + } else { + Node current = Head; + while (current.Successor != null) { + current = current.Successor; + } + current.Successor = newNode; + } + } + } +} \ No newline at end of file diff --git a/data structures/linked list/cs/LinkedList/LinkedList.csproj b/data structures/linked list/cs/LinkedList/LinkedList.csproj new file mode 100644 index 000000000..72764a664 --- /dev/null +++ b/data structures/linked list/cs/LinkedList/LinkedList.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/data structures/linked list/cs/LinkedListTest/LinkedListTest.cs b/data structures/linked list/cs/LinkedListTest/LinkedListTest.cs new file mode 100644 index 000000000..c9e70c230 --- /dev/null +++ b/data structures/linked list/cs/LinkedListTest/LinkedListTest.cs @@ -0,0 +1,31 @@ +using System; +using Collections; +using Xunit; + +namespace LinkedListTest { + public class UnitTest1 { + [Fact] + public void TestAppendOneItem () { + LinkedList list = new LinkedList (); + list.Append (42); + Assert.Equal (42, list[0]); + } + + [Fact] + public void TestAppendMultipleItem () { + LinkedList list = new LinkedList (); + list.Append (42); + list.Append (23); + list.Append (1337); + Assert.Equal (42, list[0]); + Assert.Equal (23, list[1]); + Assert.Equal (1337, list[2]); + } + + [Fact] + public void TestIndexOutOfRangeException () { + LinkedList list = new LinkedList (); + Assert.Throws(() => list[0]); + } + } +} \ No newline at end of file diff --git a/data structures/linked list/cs/LinkedListTest/LinkedListTest.csproj b/data structures/linked list/cs/LinkedListTest/LinkedListTest.csproj new file mode 100644 index 000000000..6e1093f96 --- /dev/null +++ b/data structures/linked list/cs/LinkedListTest/LinkedListTest.csproj @@ -0,0 +1,20 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + diff --git a/data structures/linked list/go/linkedlistint32.go b/data structures/linked list/go/linkedlistint32.go new file mode 100644 index 000000000..b3aa52f5d --- /dev/null +++ b/data structures/linked list/go/linkedlistint32.go @@ -0,0 +1,37 @@ +package linkedlistint32 + +import "fmt" + +type Element struct { + Value int32 + Next *Element +} + +type LinkedListInt32 struct { + First *Element + Last *Element +} + +func (ll *LinkedListInt32) push(value int32) { + newElement := Element{Value: value, Next: nil} + + if ll.First == nil { + ll.First = &newElement + } + if ll.Last == nil { + ll.Last = &newElement + } else { + ll.Last.Next = &newElement + ll.Last = &newElement + } +} + +func print(ll LinkedListInt32) { + var element = ll.First + for element.Next != nil { + fmt.Printf("%v ",element.Value); + element = element.Next + } + fmt.Printf("%v ",element.Value); +} + diff --git a/data structures/linked list/go/linkedlistint32_test.go b/data structures/linked list/go/linkedlistint32_test.go new file mode 100644 index 000000000..e0245c677 --- /dev/null +++ b/data structures/linked list/go/linkedlistint32_test.go @@ -0,0 +1,34 @@ +package linkedlistint32 + +import ( + _ "testing" + "testing" +) + +func Test(t *testing.T) { + var ll LinkedListInt32 + ll.push(11) + ll.push(12) + ll.push(55) + ll.push(67) + print(ll) + + if ll.First == nil { + t.Error("first element is empty") + } + if ll.First.Value != 11 { + t.Error("first element is not 11") + } + + if ll.First.Next.Value != 12 { + t.Error("second element is not 12") + } + + if ll.First.Next.Next.Value != 55 { + t.Error("third element is not 55") + } + + if (ll.Last.Value != 67){ + t.Error("last element is not 67") + } +} diff --git a/data structures/linked list/java/Circular Linked List/Circular_LL.java b/data structures/linked list/java/Circular Linked List/Circular_LL.java new file mode 100644 index 000000000..8af0a252e --- /dev/null +++ b/data structures/linked list/java/Circular Linked List/Circular_LL.java @@ -0,0 +1,85 @@ + +public class Circular_LL { + Node head = new Node(); + + public void print(){ + Node n=head; + while(n.next!=head){ + System .out.print(n.next.data+ " "); + n=n.next; + } + System.out.println(""); + + } + + public void insert(int x){ + Node n= head; + while(n.next!=null){ + n=n.next; + } + Node newNode = new Node(x); + newNode.next=head; + n.next=newNode; + + } + public void insertm(int x){ + Node n= head; + while(n.next!=head){ + n=n.next; + } + Node newNode = new Node(x); + newNode.next=head; + n.next=newNode; + + } + + public int count(){ + Node n=head; + int cnt=0; + while(n.next!=null){ + n=n.next; + cnt=cnt+1; + } + return cnt; + } + public void nodeAtPosition(int p){ + if(p>=0){ + System.out.print("Node at a position " +p+": "); + int cnt=0; + Node n= head; + Node temp=head; + while(n.next!=head){ + n=n.next; + cnt++; + } + Node nnode = head; + if(n.next==null){ + System.out.println("Empty list"); + } + else{ + int c; + c=0; + while(cNUllist + llist.append(6); + + // Insert 7 at the beginning. So linked list becomes + // 7->6->NUllist + llist.push(7); + + // Insert 1 at the beginning. So linked list becomes + // 1->7->6->NUllist + llist.push(1); + + // Insert 4 at the end. So linked list becomes + // 1->7->6->4->NUllist + llist.append(4); + + // Insert 8, after 7. So linked list becomes + // 1->7->8->6->4->NUllist + llist.insertAfter(llist.head.next, 8); + + System.out.println("\nCreated Linked list is: "); + llist.printList(); + } +} \ No newline at end of file diff --git a/data structures/linked list/javascript/linkedList.js b/data structures/linked list/javascript/linkedList.js new file mode 100644 index 000000000..d7d042245 --- /dev/null +++ b/data structures/linked list/javascript/linkedList.js @@ -0,0 +1,191 @@ +class ListNode { + constructor(value, next = null) { + this.value = value; + this.next = next; + } +} + +class LinkedList { + constructor() { + this._first = null; + this._last = null; + this._length = 0; + } + + get first() { + return this._first ? this._first.value : 'undefined'; + } + + get last() { + return this._last ? this._last.value : 'undefined'; + } + + get length() { + return this._length; + } + + append(...elements) { + elements.forEach((el) => { + const newNode = new ListNode(el); + if (this._first === null) { + this._first = newNode; + this._last = newNode; + } + this._last.next = newNode; + this._last = newNode; + }); + + this._length += elements.length; + + return this; + } + + prepend(...elements) { + elements.reverse().forEach((el) => { + const newNode = new ListNode(el); + if (this._first === null) { + this._first = newNode; + this._last = newNode; + } + newNode.next = this._first; + this._first = newNode; + }); + + this._length += elements.length; + + return this; + } + + insert(index, ...elements) { + if (index < 0 || index > this._length) { + throw new Error('Invalid index!'); + } + + if (index === 0) { + return this.prepend(...elements); + } else if (index === this._length) { + return this.append(...elements) + } + let nodeToInsertAfter = this._nodeAtIndex(index - 1); + + elements.forEach((el) => { + const newNode = new ListNode(el); + newNode.next = nodeToInsertAfter.next; + nodeToInsertAfter.next = newNode; + nodeToInsertAfter = newNode; + }); + + this._length += elements.length; + + return this; + } + + at(index, value) { + this._validateIndex(index); + + let nodeToReturn = this._nodeAtIndex(index); + if (typeof value === 'undefined') { + nodeToReturn.value = value; + } + + return nodeToReturn.value; + } + + removeAt(index) { + this._validateIndex(index); + + if (index === 0) { + const result = this._first.value; + this._first = this._first.next; + + if (this._length === 1) { + this._last = null; + } + + this._length -= 1; + + return result; + } + let nodeToRemoveAfter = this._nodeAtIndex(index - 1); + const result = nodeToRemoveAfter.next.value; + nodeToRemoveAfter.next = nodeToRemoveAfter.next.next; + + if (index === this._length - 1) { + this._last = nodeToRemoveAfter; + } + + this._length -= 1; + + return result; + + } + + *[Symbol.iterator]() { + let nextNode = this._first; + while (nextNode !== null) { + yield nextNode.value; + nextNode = nextNode.next; + } + } + + toArray() { + return [...this]; + } + + toString() { + return this.toArray().join(' -> '); + } + + _validateIndex(index) { + if (index < 0 || index >= this._length) { + throw new Error('Invalid index!'); + } + } + + _nodeAtIndex(index) { + let node = this._first; + for (let i = 0; i < index; i++) { + node = node.next; + } + + return node; + } +} + +class Queue { + constructor() { + this._linkedList = new LinkedList(); + } + + enqueue(value) { + this._linkedList.append(value); + return this; + } + + dequeue() { + return this._linkedList.length ? this._linkedList.removeAt(0) : null; + } + + get length() { + return this._linkedList.length; + } +} + +class Stack { + constructor() { + this._linkedList = new LinkedList(); + } + + push(value) { + this._linkedList.prepend(value); + return this; + } + + pop() { + return this._linkedList.length ? this._linkedList.removeAt(0) : null; + } + + get length() { + return this._linkedList.length; + } +} \ No newline at end of file diff --git a/data structures/linked list/python/Queue_with_Singly_Linked_List.py b/data structures/linked list/python/Queue_with_Singly_Linked_List.py new file mode 100644 index 000000000..9d1002e6f --- /dev/null +++ b/data structures/linked list/python/Queue_with_Singly_Linked_List.py @@ -0,0 +1,57 @@ +class Node: + def __init__(self,data=None,next_node=None): + self.data = data + self.next_node = next_node + + def get_data(self): + return self.data + + def get_next(self): + return self.next_node + + def set_next(self,new_node): + self.next_node = new_node + + +class Queue: + def __init__(self,head=None): + self.head = head + + def enqueue(self,data): + new_item = Node(data) + current = self.head + if current is None: + self.head = new_item + else: + while current.get_next(): + current = current.get_next() + current.set_next(new_item) + + def dequeue(self): + current = self.head + if current != None: + self.head = current.get_next() + else: + print("Queue is empty") + + def size(self): + current = self.head + count = 0 + while current: + count +=1 + current = current.get_next() + return count + + def print_queue(self): + current = self.head + temp = [] + while current: + temp.append(current.get_data()) + current = current.get_next() + return temp + + def is_empty(self): + if self.head == None: + print("Queue is empty!") + else: + print("Queue isn't empty!") diff --git a/data structures/linked list/python/Singly-linked-list.py b/data structures/linked list/python/Singly-linked-list.py new file mode 100644 index 000000000..a8f525867 --- /dev/null +++ b/data structures/linked list/python/Singly-linked-list.py @@ -0,0 +1,67 @@ +class Node: + def __init__(self,data,next_node=None): + self.data = data + self.next_node = next_node + + def get_data(self): + return self.data + + def get_next(self): + return self.next_node + + def set_next(self,new_node): + self.next_node = new_node + + +class Linked_list: + def __init__(self,head=None): + self.head = head + + def insert_head(self,data): + new_node = Node(data) + new_node.set_next(self.head) + self.head = new_node + + def insert_tail(self,data): + new_node = Node(data) + current = self.head + if current is None: + self.head = new_node + else: + while current.get_next(): + current = current.get_next() + current.set_next(new_node) + + def delete(self,data): + current = self.head + prev = None + while current: + if current.get_data() == data: + if prev: + prev.set_next(current.get_next()) + else: + self.head = current.get_next() + break + else: + prev = current + current = current.get_next() + + def search(self,data): + current = self.head + while current: + if current.get_data() == data: + return True + else: + current = current.get_next() + return False + + def print_list(self): + current = self.head + self.temp = [] + while current: + self.temp.append(current.get_data()) + current = current.get_next() + print(self.temp) + + def __len__(self): + return len(self.temp) diff --git a/data structures/linked list/python/Stack_with_Singly_Linked_List.py b/data structures/linked list/python/Stack_with_Singly_Linked_List.py new file mode 100644 index 000000000..813c96b83 --- /dev/null +++ b/data structures/linked list/python/Stack_with_Singly_Linked_List.py @@ -0,0 +1,50 @@ +class Node: + def __init__(self,data=None,next_node=None): + self.data = data + self.next_node = next_node + + def get_data(self): + return self.data + + def get_next(self): + return self.next_node + + def set_next(self,new_node): + self.next_node = new_node + + +class Stack: + def __init__(self,head=None): + self.head = head + + def push(self,data): + new_item = Node(data) + current = self.head + if current is None: + self.head = new_item + else: + while current.get_next(): + current = current.get_next() + current.set_next(new_item) + + def pop(self): + current = self.head + prev = None + if current is not None: + while current.get_next(): + prev = current + current = current.get_next() + if prev: + prev.set_next(current.get_next()) + else: + self.head = current.get_next() + else: + print("Empty stack!") + + def print_stack(self): + current = self.head + temp = [] + while current: + temp.append(current.get_data()) + current = current.get_next() + return temp diff --git a/data structures/queue/c/queue b/data structures/queue/c/queue new file mode 100644 index 000000000..d8ffc58f8 Binary files /dev/null and b/data structures/queue/c/queue differ diff --git a/data structures/queue/c/queue_using_array.c b/data structures/queue/c/queue_using_array.c index a0572f1ad..38e298c80 100644 --- a/data structures/queue/c/queue_using_array.c +++ b/data structures/queue/c/queue_using_array.c @@ -3,55 +3,37 @@ #define MAX 500 -struct Queue +typedef struct Queue { int size; int *a; int front; int rear; -}; +} queue; -typedef struct Queue queue; - -queue *createQueue() +queue* createQueue() { queue *q = malloc(sizeof(queue)); q->size = 0; q->front = 0; q->rear = 0; - q->a = malloc(MAX * sizeof(int)); + q->a = calloc(MAX, sizeof(int)); } int isEmpty(queue *q) { - if (q->size == 0) - { - return 1; - } - else - { - return 0; - } + return q->size == 0; } int isFull(queue *q) { - if (q->size == MAX) - { - return 1; - } - else - { - return 0; - } + return q->size == MAX; } void enqueue(queue *q, int n) { - if (isFull(q)) - { - printf("Queue is full.\n"); - } + if (isFull(q)) + printf("Queue is full.\n"); else { (q->rear)++; @@ -63,10 +45,8 @@ void enqueue(queue *q, int n) void dequeue(queue *q) { - if (isEmpty(q)) - { - printf("Queue is empty.\n"); - } + if (isEmpty(q)) + printf("Queue is empty.\n"); else { printf("%d dequeued from the queue.\n", q->a[++q->front]); @@ -76,34 +56,28 @@ void dequeue(queue *q) int peek(queue *q) { - if (isEmpty(q)) - { - printf("Queue is empty.\n"); - } - else - { - return q->a[q->front]; - } + if (isEmpty(q)) + printf("Queue is empty.\n"); + else + return q->a[q->front]; } void display(queue *q) { - int i = 0; - for (i = q->front + 1; i < q->rear + 1; i++) - { + for (int i = q->front + 1; i < q->rear + 1; i++) printf("%d\t", q->a[i]); - } + printf("\n"); } int main() { queue *q = createQueue(); - int c = 0; - printf("Enter 1 to enqueue elements in queue.\nEnter 2 to dequeue element from the queue.\nEnter 3 to peek topmost element in queue.\nEnter 4 to display content of the queue.\n"); - scanf("%d", &c); + int c = 0; do { + printf("\nEnter 1 to enqueue elements in queue.\nEnter 2 to dequeue element from the queue.\nEnter 3 to peek topmost element in queue.\nEnter 4 to display content of the queue.\n"); + scanf("%d", &c); switch (c) { case 1: @@ -124,7 +98,6 @@ int main() default: printf("Invalid input.\n"); } - scanf("%d", &c); } while (c != -1); return 0; } \ No newline at end of file diff --git a/data structures/queue/c/queue_using_stack.c b/data structures/queue/c/queue_using_stack.c new file mode 100644 index 000000000..3c7a84eee --- /dev/null +++ b/data structures/queue/c/queue_using_stack.c @@ -0,0 +1,89 @@ +/* C Program to implement a queue using two stacks */ +#include +#include +/* structure of a stack node */ +struct sNode +{ + int data; + struct sNode* next; +}; +void push(struct sNode** top_ref, int new_data); +int pop(struct sNode** top_ref); +/* structure of queue having two stacks */ +struct queue +{ + struct sNode* stack1; + struct sNode* stack2; +}; +void enQueue(struct queue* q, int x) +{ + push(&q->stack1, x); +} +int deQueue(struct queue* q) +{ + int x; + if (q->stack1 == NULL && q->stack2 == NULL) + { + printf("Q is empty"); + getchar(); + exit(0); + } +/* Move elements from stack1 to stack 2 only if + stack2 is empty */ + if (q->stack2 == NULL) + { + while (q->stack1 != NULL) + { + x = pop(&q->stack1); + push(&q->stack2, x); + } + } + x = pop(&q->stack2); + return x; +} +void push(struct sNode** top_ref, int new_data) +{ + struct sNode* new_node = (struct sNode*)malloc(sizeof(struct sNode)); + if (new_node == NULL) + { + printf("Stack overflow \n"); + getchar(); + exit(0); + } + new_node->data = new_data; + new_node->next = (*top_ref); + (*top_ref) = new_node; +} +int pop(struct sNode** top_ref) +{ + int res; + struct sNode* top; + if (*top_ref == NULL) + { + printf("Stack underflow \n"); + getchar(); + exit(0); + } + else + { + top = *top_ref; + res = top->data; + *top_ref = top->next; + free(top); + return res; + } +} +int main() +{ + struct queue* q = (struct queue*)malloc(sizeof(struct queue)); + q->stack1 = NULL; + q->stack2 = NULL; + enQueue(q, 1); + enQueue(q, 2); + enQueue(q, 3); + printf("%d ", deQueue(q)); + printf("%d ", deQueue(q)); + printf("%d ", deQueue(q)); + return 0; +} + diff --git a/data structures/queue/cpp/CircularQueue.cpp b/data structures/queue/cpp/CircularQueue.cpp new file mode 100644 index 000000000..0348311ad --- /dev/null +++ b/data structures/queue/cpp/CircularQueue.cpp @@ -0,0 +1,111 @@ +#include + +using namespace std; + +int size; +class cqueue +{ + int a[50],front = -1, rear = -1,x; +public: + void insert(); + void del(); + void show(); +}; + +void cqueue::insert() +{ + char ch = 'y'; + while(ch == 'y' || ch == 'Y') + { + cout<<"\nEnter Element : "; + cin>>x; + if(rear == (size - 1) && front == 0 || rear ==(front-1)) + { + cout<<"\nOverflow!"; + break; + } + else if(front == -1 && rear == -1) + { + front = rear = 0; + a[rear] = x; + } + else if(rear == (size -1) && front > 0) + { + rear = 0; + a[rear] = x; + } + else + a[++rear] = x; + cout<<"\nDo you want to enter more?(y/n)..."; + cin>>ch; + } +} + +void cqueue::del() +{ + if(front == -1) + cout<<"\nUnderflow!"; + else if(front == rear) + { + cout<front) + { + for(int i = front ;i<=rear;i++) + cout<>size; + while(1) + { + cout<<"\nMENU\n1.Insert\n2.Delete\n3.Show\n4.Exit"; + cout<<"\nEnter your choice : "; + cin>>ch; + switch(ch) + { + case 1: o.insert(); + break; + case 2: o.del(); + break; + case 3: o.show(); + break; + case 4: exit(0); + default : cout<<"\nInvalid Choice!"; + break; + } + } + + return 0; +} diff --git a/data structures/queue/cpp/QueueUsingFunctionCallStack.cpp b/data structures/queue/cpp/QueueUsingFunctionCallStack.cpp new file mode 100644 index 000000000..47000eb94 --- /dev/null +++ b/data structures/queue/cpp/QueueUsingFunctionCallStack.cpp @@ -0,0 +1,56 @@ +// CPP program to implement Queue using +// one stack and recursive call stack. +#include +using namespace std; + +struct Queue { + stack s; + + // Enqueue an item to the queue + void enQueue(int x) + { + s.push(x); + } + + // Dequeue an item from the queue + int deQueue() + { + if (s.empty()) { + cout << "Q is empty"; + exit(0); + } + + // pop an item from the stack + int x = s.top(); + s.pop(); + + // if stack becomes empty, return + // the popped item + if (s.empty()) + return x; + + // recursive call + int item = deQueue(); + + // push popped item back to the stack + s.push(x); + + // return the result of deQueue() call + return item; + } +}; + +// Driver code +int main() +{ + Queue q; + q.enQueue(1); + q.enQueue(2); + q.enQueue(3); + + cout << q.deQueue() << '\n'; + cout << q.deQueue() << '\n'; + cout << q.deQueue() << '\n'; + + return 0; +} diff --git a/data structures/queue/cpp/QueueUsingTwoStacks.cpp b/data structures/queue/cpp/QueueUsingTwoStacks.cpp new file mode 100644 index 000000000..978f21239 --- /dev/null +++ b/data structures/queue/cpp/QueueUsingTwoStacks.cpp @@ -0,0 +1,56 @@ +// CPP program to implement Queue using +// two stacks with costly enQueue() +#include +using namespace std; + +struct Queue { + stack s1, s2; + + void enQueue(int x) + { + // Move all elements from s1 to s2 + while (!s1.empty()) { + s2.push(s1.top()); + s1.pop(); + } + + // Push item into s1 + s1.push(x); + + // Push everything back to s1 + while (!s2.empty()) { + s1.push(s2.top()); + s2.pop(); + } + } + + // Dequeue an item from the queue + int deQueue() + { + // if first stack is empty + if (s1.empty()) { + cout << "Q is Empty"; + exit(0); + } + + // Return top of s1 + int x = s1.top(); + s1.pop(); + return x; + } +}; + +// Driver code +int main() +{ + Queue q; + q.enQueue(1); + q.enQueue(2); + q.enQueue(3); + + cout << q.deQueue() << '\n'; + cout << q.deQueue() << '\n'; + cout << q.deQueue() << '\n'; + + return 0; +} diff --git a/data structures/queue/python/Queue.ipynb b/data structures/queue/python/Queue.ipynb new file mode 100644 index 000000000..f135d12f9 --- /dev/null +++ b/data structures/queue/python/Queue.ipynb @@ -0,0 +1,628 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import division\n", + "from math import floor\n", + "\n", + "from IPython.display import Image" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Queue\n", + "\n", + "i. It is **linear data structure** follows a particular order in which the operations are performed \n", + "\n", + "ii. Follows **First In First Out (FIFO) pattern**\n", + "\n", + "iii. Simple example of a queue is any queue of consumers for a resource, in which customer that comes first is served first.\n", + "\n", + "### Queue vs Stack\n", + "\n", + "Difference between queue and stack is that, in stack we remove the item that is mostly recently added. In Queue, we remove the item that is least recently added(oldest one gets eliminated first) \n", + "\n", + "### Applications\n", + "\n", + "Queue is used when things needs to be processed immediately, but have to processed in **First in First Out(FIFO)** order like Breadth First Search. Queue is useful when : \n", + "\n", + "i. When a resource is shared among multiple consumers. Examples include CPU scheduling, Disk Scheduling.\n", + "\n", + "ii. When data is transferred asynchronously (data not necessarily received at same rate as sent) between two processes. Examples include IO Buffers, pipes, file IO, etc.\n", + "\n", + "### Types of Queue: \n", + "\n", + "There are four types of queue:\n", + "\n", + "i. Simple/Normal Queue \n", + "\n", + "ii. Circular Queue \n", + "\n", + "iii. Priority Queue\n", + "\n", + "iv. Dequeue (Double Ended Queue)\n", + "\n", + "### Implementation Ways of Queue: \n", + "\n", + "There are two ways to implement queue:\n", + "\n", + "i. Arrays : Both stacks and queues can be implemented with arrays. \n", + "\n", + " i. The problem with this approach is that **arrays static data structures — they have a fixed size**. \n", + " \n", + " ii. If your **stack or queue doesn’t use up the maximum space allotted by the array, you’re wasting memory**.\n", + " \n", + " iii. If it has ** too many elements, the array won’t be able to hold them all, and you’ll get an index out of bounds error.**\n", + " \n", + "\n", + "ii. Linked List" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implementation of Queue using Array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Implementation of Normal Queue" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "\n", + "# Insert, Delete \n", + "class Queue:\n", + " \n", + " def __init__(self, capacity):\n", + " \n", + " self.rear = -1\n", + " self.front = -1\n", + " self.capacity = capacity\n", + " self.queue = [None] * self.capacity #default queue size\n", + " \n", + " \n", + " def isQueueEmpty(self):\n", + " \n", + " if self.rear == -1 and self.front == -1 :\n", + " return True\n", + " else:\n", + " return False\n", + " \n", + " \n", + " def isQueueFull(self):\n", + " \n", + " if self.rear == len(self.queue)-1:\n", + " \n", + " return True\n", + " else:\n", + " return False\n", + " \n", + " \n", + " def insert(self, element):\n", + " \n", + " if self.isQueueFull():\n", + " print \"Queue Full\"\n", + " return\n", + " \n", + " elif self.isQueueEmpty():\n", + " \n", + " self.rear = 0\n", + " self.front = 0 \n", + " self.queue[self.rear] = element\n", + " \n", + " else:\n", + " self.rear += 1\n", + " self.queue[self.rear] = element\n", + " \n", + " print \"queue \", self.queue\n", + " print \"rear \", self.rear\n", + " print \"front \", self.front\n", + " \n", + " \n", + " def delete(self):\n", + " \n", + " if self.isQueueEmpty():\n", + " return\n", + " elif self.front == self.rear:\n", + " self.front = -1\n", + " self.rear = -1 \n", + " self.queue = [None] * self.capacity\n", + " print \"Array Empty\"\n", + " else:\n", + " self.front += 1\n", + " print \"front \", self.front\n", + " \n", + " print \"queue \", self.queue[self.front:]\n", + " \n", + " \n", + " \n", + "queue = Queue(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "queue [4, None, None]\n", + "rear 0\n", + "front 0\n" + ] + } + ], + "source": [ + "queue.insert(4)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[4, None, None]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "queue.queue" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Array Empty\n" + ] + } + ], + "source": [ + "queue.delete()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Draw backs in Normal/Simple Queue\n", + "\n", + "We cannot use space of removed elements for example: If our queue contains three elements [780, 30, 64], and we remove/delete one element from the queue then our queue will hava [30, 64]. So now, if we want to insert any new element in the queue then we cannot insert any other element in the queue as implementation of queue will show that queue is full. In other words, we cannot use space of element that is removed from the queue.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion of Normal/Simple Queue\n", + "\n", + "If there are three elements in the queue: [1,2,3], If we deQueue the first element updated queue is: [2, 3]. Now even if we try to insert new element, we cannot insert because right side of the queue is still full. We can only use the queue once all the elements are removed. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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\nAAAASUVORK5CYII=\n", + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "Image(filename=\"./images/drawBackSimpleQueue.png\")\n", + "# source Quora" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Circular Queue" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "\n", + "# Insert, Delete \n", + "class CircularQueue:\n", + " \n", + " def __init__(self, capacity):\n", + " \n", + " self.rear = -1\n", + " self.front = -1\n", + " self.capacity = capacity\n", + " self.queue = [None] * self.capacity #default queue size\n", + " \n", + " \n", + " def isQueueEmpty(self):\n", + " \n", + " if self.rear == -1 and self.front == -1 :\n", + " return True\n", + " else:\n", + " return False\n", + " \n", + " \n", + " def isQueueFull(self):\n", + " \n", + " if (self.rear + 1) % self.capacity == self.front:\n", + " return True\n", + " else:\n", + " return False\n", + " \n", + " \n", + " def insert(self, element):\n", + " \n", + " if self.isQueueFull():\n", + " print \"Queue Full\"\n", + " return\n", + " \n", + " elif self.isQueueEmpty():\n", + " \n", + " self.rear = 0\n", + " self.front = 0 \n", + " self.queue[self.rear] = element\n", + " \n", + " else:\n", + " self.rear = (self.rear + 1) % self.capacity\n", + " self.queue[self.rear] = element\n", + " \n", + " print \"queue \", self.queue\n", + " print \"rear \", self.rear\n", + " print \"front \", self.front\n", + " \n", + " \n", + " def delete(self):\n", + " \n", + " if self.isQueueEmpty():\n", + " return\n", + " elif self.front == self.rear:\n", + " self.front = -1\n", + " self.rear = -1 \n", + " self.queue = [None] * self.capacity\n", + " print \"Array Empty\"\n", + " else:\n", + " self.queue[self.front] = None\n", + " self.front = (self.front + 1) % self.capacity\n", + " print \"front \", self.front\n", + " \n", + " print \"queue \", self.queue\n", + " \n", + " \n", + " \n", + "queue = CircularQueue(3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "queue.insert(300)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "queue.queue" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "queue.delete()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Conclusion of Circular Queue\n", + "\n", + "Time Complexity: Time complexity of enQueue(), deQueue() operation is O(1) as there is no loop in any of the operation.\n", + "\n", + "#### Applications:\n", + "\n", + "##### Memory Management: \n", + "\n", + "The unused memory locations in the case of ordinary queues can be utilized in circular queues.\n", + "\n", + "\n", + "##### Traffic system: \n", + "\n", + "In computer controlled traffic system, circular queues are used to switch on the traffic lights one by one repeatedly as per the time set.\n", + "\n", + "\n", + "##### CPU Scheduling: \n", + "\n", + "Operating systems often maintain a queue of processes that are ready to execute or that are waiting for a particular event to occur.\n", + "\n", + "\n", + "## Problem in Normal Queue\n", + "\n", + "In a normal Queue, we can insert elements until queue becomes full. But once queue becomes full, we can not insert the next element even if there is a space in front of queue.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "## Priority Queue\n", + "\n", + "### Motivation of priority Queue\n", + "\n", + "There are scenarios where element with highest priority should be handled first or given more preferences. \n", + "\n", + "Priority queues are a kind of abstract data type(means it can be implemented using other data structures also) that generalizes the queue. Their **principles are exactly the same** **except** that they also **include a priority for every value in the queue.** When a value is inserted, a priority is assigned to it. The value with the highest priority is always removed first. However, when two values have same priority, then we follow FIFO rule\n", + "\n", + "You can think of priority queues like a hospital. Treating patients in a first-in-first-out (FIFO) approach isn't always a good idea because some patients may be in critical condition. So, a patient who has a cough may come in and be assigned a low priority. Then a patient may come in later who has a gunshot wound, and they would be given a high priority and then be treated first.\n", + "\n", + "### Types of Priority Queue\n", + "\n", + "** i. Ascending priority queue(implementation same as min heap): ** \n", + "\n", + "**Lower priority given to higher value and highest priority given to lower value**. For example: [1,2,3,4,5] so here number 1 has highest priority and number 5 has lowest priority\n", + "\n", + "** ii. Descending priority queue(implementation same as max heap): **\n", + "\n", + "**Lower priority given to lower value and highest priority given to higher value**. For example: [5,4,3,2,1] so here number 5 has highest priority and number 1 has lowest priority\n", + "\n", + "\n", + "### Implementation Method of Priority Queue \n", + "\n", + "Priority queue can be implemented using arrays. For efficient implementation, we should consider concept of **Heaps(specially binary heap)** as it requires less complexity. \n", + "\n", + "### Applications of Priority Queue\n", + "\n", + "**Dijkstra’s Shortest Path Algorithm using priority queue**: When the graph is stored in the form of adjacency list or matrix, priority queue can be used to extract minimum efficiently when implementing Dijkstra’s algorithm.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Binary Heap\n", + "\n", + "The **heap, or better priority queue**, as abstract data structure usually supports operations like is-empty, add-element, delete-min. And usually not find-element. \n", + "\n", + "However, there are other types of heaps also instead of binary heap. Such as **Binomail heap** in which parent can have more than 2 children\n", + "\n", + "So if we want to search element in binary heap we have to search all the elements (complexity: O(N)) in worst case.\n", + "\n", + "### Operations: \n", + "\n", + "i. Insert\n", + "\n", + "ii. Delete\n", + "\n", + "**Note: We cannot pass complete array once and expect algorithm to arrange in binary heap. Therefore, when any new element is inserted, algorithm arranges the array based on min/max heap**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "class BinaryHeap:\n", + " \n", + " \n", + " def __init__(self):\n", + " \n", + " self.array = []\n", + " \n", + " \n", + " def DoMinHeap(self, i):\n", + " \n", + " smallest = i\n", + " left_i = 2*i + 1\n", + " right_i = 2*i + 2\n", + " \n", + " \n", + " if left_i < len(self.array) and self.array[i] > self.array[left_i]:\n", + " smallest = left_i\n", + " \n", + " if right_i < len(self.array) and self.array[i] > self.array[right_i]:\n", + " smallest = right_i\n", + " \n", + " if smallest != i:\n", + " self.array[i], self.array[smallest] = self.array[smallest], self.array[i]\n", + "# print (\"smallest changed \", smallest)\n", + " self.DoMinHeap(smallest)\n", + " \n", + " \n", + " def DoMaxHeap(self, i):\n", + "\n", + " largest = i\n", + " left_i = 2*i + 1\n", + " right_i = 2*i + 2\n", + "\n", + " if right_i < len(self.array) and self.array[i] < self.array[right_i]:\n", + " largest = right_i\n", + " \n", + " if left_i < len(self.array) and self.array[i] < self.array[left_i]:\n", + " largest = left_i\n", + "\n", + "\n", + "\n", + " if largest != i:\n", + " self.array[i], self.array[largest] = self.array[largest], self.array[i]\n", + " self.DoMaxHeap(largest)\n", + " \n", + " \n", + " def insert(self, element):\n", + " \n", + " self.array.append(element)\n", + " return self.main()\n", + " \n", + " \n", + " def delete(self):\n", + " \n", + " #swap first and last element \n", + " # remove last element\n", + " first_element = 0\n", + " self.array[-1], self.array[first_element] = self.array[first_element], self.array[-1]\n", + " self.array = self.array[0:-1]\n", + " \n", + " return self.main()\n", + " \n", + " \n", + " def main(self):\n", + " \n", + " #because after half size of array, there would be left and right children\n", + " arrSize = int(floor(len(self.array)/2))\n", + " \n", + " for i in range(arrSize, -1, -1):\n", + " print (\"i, \", i)\n", + "# self.DoMinHeap(i)\n", + " self.DoMaxHeap(i)\n", + "# if i == 0:\n", + "# break\n", + " return self.array\n", + " \n", + "input_array = [6, 4, 2, 3, 1]\n", + "print \"Input array \", input_array, \"\\n\"\n", + "\n", + "# bheap = BinaryHeap(input_array)\n", + "bheap = BinaryHeap()\n", + "print \"Min heap\", bheap.main()\n", + "\n", + "# new_num = 0\n", + "# print \"insert new number \", new_num\n", + "print \"min heap after inserting new number \", bheap.insert(17)\n", + "# print \"Min heap after removing first element \", bheap.delete()\n", + "print \"\"\n", + "print \"===============================Summary===================================\"\n", + "print \"Space Complexity: O(n)\"\n", + "print \"Search Complexity: O(n)\"\n", + "print \"Deletion: O(log n) because after removing element we again have to call heapify function\"\n", + "print \"Insertion: O(Log n) because again after inserting we have to call heapify function\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bheap.insert(-42)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bheap.delete()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Applications of Heaps \n", + "\n", + "1) **Heap Sort:** Heap Sort uses Binary Heap to sort an array in O(nLogn) time.\n", + "\n", + "2) **Priority Queue:** Priority queues can be efficiently implemented using Binary Heap because it supports insert(), delete() and extractmax(), decreaseKey() operations in O(logn) time. Binomoial Heap and Fibonacci Heap are variations of Binary Heap. These variations perform union also efficiently.\n", + "\n", + "3) **Graph Algorithms:** The priority queues are especially used in Graph Algorithms like Dijkstra’s Shortest Path and Prim’s Minimum Spanning Tree.\n", + "\n", + "4) Many problems can be efficiently solved using Heaps.\n", + "\n", + "\n", + "a) K’th Largest Element in an array.\n", + "\n", + "b) Sort an almost sorted array/\n", + "\n", + "c) Merge K Sorted Arrays." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/data structures/queue/python/images/drawBackSimpleQueue.png b/data structures/queue/python/images/drawBackSimpleQueue.png new file mode 100644 index 000000000..b63a1577d Binary files /dev/null and b/data structures/queue/python/images/drawBackSimpleQueue.png differ diff --git a/data structures/queue/queue-commonjs.js b/data structures/queue/queue-commonjs.js new file mode 100644 index 000000000..c697ea55d --- /dev/null +++ b/data structures/queue/queue-commonjs.js @@ -0,0 +1,13 @@ +const queue = []; + +module.exports = { + get: function() { + queue.shift(); + }, + add: function(item) { + queue.push(item); + }, + clear: function() { + queue = []; + } +} diff --git a/data structures/queue/scala/enqueue.scala b/data structures/queue/scala/enqueue.scala new file mode 100644 index 000000000..1c922f049 --- /dev/null +++ b/data structures/queue/scala/enqueue.scala @@ -0,0 +1,25 @@ +scala> import scala.collection.mutable.Queue +import scala.collection.mutable.Queue + +// create an empty queue +scala> var q = new Queue[String] +q: scala.collection.mutable.Queue[String] = Queue() + +// add elements to the queue in the usual ways +scala> var q = new Queue[String] +q: scala.collection.mutable.Queue[String] = Queue() + +scala> q += "apple" +res0: scala.collection.mutable.Queue[String] = Queue(apple) + +scala> q += ("kiwi", "banana") +res1: scala.collection.mutable.Queue[String] = Queue(apple, kiwi, banana) + +scala> q ++= List("cherry", "coconut") +res2: scala.collection.mutable.Queue[String] = Queue(apple, kiwi, banana, cherry, coconut) + +// can also use enqueue +scala> q.enqueue("pineapple") + +scala> q +res3: scala.collection.mutable.Queue[String] = Queue(apple, kiwi, banana, cherry, coconut, pineapple) diff --git a/data structures/queue/ts/queue.ts b/data structures/queue/ts/queue.ts new file mode 100644 index 000000000..208471d55 --- /dev/null +++ b/data structures/queue/ts/queue.ts @@ -0,0 +1,12 @@ +export class Queue { + _store: T[] = []; + push(val: T) { + this._store.push(val); + } + pop(): T | undefined { + return this._store.shift(); + } + lenght() : number { + return this._store.length; + } +} \ No newline at end of file diff --git a/data structures/skipList.h b/data structures/skipList.h new file mode 100644 index 000000000..1e8df1144 --- /dev/null +++ b/data structures/skipList.h @@ -0,0 +1,160 @@ +#pragma once +#include + +using namespace std; + +// Class to implement node +class Node +{ +public: + int key; + + // Array to hold pointers to node of different level + Node **forward; + Node(int, int); +}; + +Node::Node(int key, int level) +{ + this->key = key; + + // Allocate memory to forward + forward = new Node*[level + 1]; + + // Fill forward array with 0(NULL) + memset(forward, 0, sizeof(Node*)*(level + 1)); +}; + +// Class for Skip list +class SkipList +{ + // Maximum level for this skip list + int MAXLVL; + + // P is the fraction of the nodes with level + // i pointers also having level i+1 pointers + float P; + + // current level of skip list + int level; + + // pointer to header node + Node *header; +public: + SkipList(int, float); + int randomLevel(); + Node* createNode(int, int); + void insertElement(int); + void displayList(); +}; + +SkipList::SkipList(int MAXLVL, float P) +{ + this->MAXLVL = MAXLVL; + this->P = P; + level = 0; + + // create header node and initialize key to -1 + header = new Node(-1, MAXLVL); +}; + +// create random level for node +int SkipList::randomLevel() +{ + float r = (float)rand() / RAND_MAX; + int lvl = 0; + while (r < P && lvl < MAXLVL) + { + lvl++; + r = (float)rand() / RAND_MAX; + } + return lvl; +}; + +// create new node +Node* SkipList::createNode(int key, int level) +{ + Node *n = new Node(key, level); + return n; +}; + +// Insert given key in skip list +void SkipList::insertElement(int key) +{ + Node *current = header; + + // create update array and initialize it + Node *update[MAXLVL + 1]; + memset(update, 0, sizeof(Node*)*(MAXLVL + 1)); + + /* start from highest level of skip list + move the current pointer forward while key + is greater than key of node next to current + Otherwise inserted current in update and + move one level down and continue search + */ + for (int i = level; i >= 0; i--) + { + while (current->forward[i] != NULL && + current->forward[i]->key < key) + current = current->forward[i]; + update[i] = current; + } + + /* reached level 0 and forward pointer to + right, which is desired position to + insert key. + */ + current = current->forward[0]; + + /* if current is NULL that means we have reached + to end of the level or current's key is not equal + to key to insert that means we have to insert + node between update[0] and current node */ + if (current == NULL || current->key != key) + { + // Generate a random level for node + int rlevel = randomLevel(); + + // If random level is greater than list's current + // level (node with highest level inserted in + // list so far), initialize update value with pointer + // to header for further use + if (rlevel > level) + { + for (int i = level + 1; iforward[i] = update[i]->forward[i]; + update[i]->forward[i] = n; + } + cout << "Successfully Inserted key " << key << "\n"; + } +}; + +// Display skip list level wise +void SkipList::displayList() +{ + cout << "\n*****Skip List*****" << "\n"; + for (int i = 0; i <= level; i++) + { + Node *node = header->forward[i]; + cout << "Level " << i << ": "; + while (node != NULL) + { + cout << node->key << " "; + node = node->forward[i]; + } + cout << "\n"; + } +}; \ No newline at end of file diff --git a/data structures/stack/c/stack_in_c.c b/data structures/stack/c/stack_in_c.c new file mode 100644 index 000000000..e3fcfeb02 --- /dev/null +++ b/data structures/stack/c/stack_in_c.c @@ -0,0 +1,221 @@ + /* + + * C program to implement stack. Stack is a LIFO data structure. + + * Stack operations: PUSH(insert operation), POP(Delete operation) + + * and Display stack. + + */ + + #include + + #define MAXSIZE 5 + + + + struct stack + + { + + int stk[MAXSIZE]; + + int top; + + }; + + typedef struct stack STACK; + + STACK s; + + + + void push(void); + + int pop(void); + + void display(void); + + + + void main () + + { + + int choice; + + int option = 1; + + s.top = -1; + + + + printf ("STACK OPERATION\n"); + + while (option) + + { + + printf ("------------------------------------------\n"); + + printf (" 1 --> PUSH \n"); + + printf (" 2 --> POP \n"); + + printf (" 3 --> DISPLAY \n"); + + printf (" 4 --> EXIT \n"); + + printf ("------------------------------------------\n"); + + + + printf ("Enter your choice\n"); + + scanf ("%d", &choice); + + switch (choice) + + { + + case 1: + + push(); + + break; + + case 2: + + pop(); + + break; + + case 3: + + display(); + + break; + + case 4: + + return; + + } + + fflush (stdin); + + printf ("Do you want to continue(Type 0 or 1)?\n"); + + scanf ("%d", &option); + + } + + } + + /* Function to add an element to the stack */ + + void push () + + { + + int num; + + if (s.top == (MAXSIZE - 1)) + + { + + printf ("Stack is Full\n"); + + return; + + } + + else + + { + + printf ("Enter the element to be pushed\n"); + + scanf ("%d", &num); + + s.top = s.top + 1; + + s.stk[s.top] = num; + + } + + return; + + } + + /* Function to delete an element from the stack */ + + int pop () + + { + + int num; + + if (s.top == - 1) + + { + + printf ("Stack is Empty\n"); + + return (s.top); + + } + + else + + { + + num = s.stk[s.top]; + + printf ("poped element is = %dn", s.stk[s.top]); + + s.top = s.top - 1; + + } + + return(num); + + } + + /* Function to display the status of the stack */ + + void display () + + { + + int i; + + if (s.top == -1) + + { + + printf ("Stack is empty\n"); + + return; + + } + + else + + { + + printf ("\n The status of the stack is \n"); + + for (i = s.top; i >= 0; i--) + + { + + printf ("%d\n", s.stk[i]); + + } + + } + + printf ("\n"); + + } \ No newline at end of file diff --git a/data structures/stack/cpp/Stack.cpp b/data structures/stack/cpp/Stack.cpp new file mode 100644 index 000000000..ae87145a4 --- /dev/null +++ b/data structures/stack/cpp/Stack.cpp @@ -0,0 +1,138 @@ +#include + +using namespace std; + +struct node +{ + int info; + node *link; +}; + +class stak +{ + node *ptr,*top = NULL,*a; + int pos = 0 , x, item; + char ch='y'; +public: + void push(); + void pop(); + void show(); + void search(); +}; + +void stak::push() +{ + ch = 'y'; + while(ch == 'y' || ch == 'Y') + { + cout<<"\nEnter element : "; + cin>>x; + ptr = new node; + ptr -> info = x; + ptr -> link = NULL; + if(top == NULL) + { + top = ptr; + } + else + { + ptr -> link = top; + top = ptr; + } + cout<<"\nWant to enter more elements?(y/n)..."; + cin>>ch; + } +} + +void stak::pop() +{ + ch = 'y'; + while(ch == 'Y' || ch == 'y') + { + if(top == NULL) + { + cout<<"\nUNDERFLOW!"; + break; + } + a = top; + top = top -> link; + cout<info<<" Deleted successfullly!\n "; + delete(a); + pos -= 1; + cout<<"\nWant to delete more?(y/n)..."; + cin>>ch; + } +} + +void stak::show() +{ + pos = 0; + if(top == NULL) + { + cout<<"\nThe list is empty!"; + return; + } + cout<<"\nThe List is : "; + while(top != NULL) + { + cout<info <<"--> "; + top = top -> link; + pos++; + } +} + +void stak::search() +{ + int tmp; + ch ='y'; + while(ch == 'y' || ch== 'Y') + { + tmp = pos; + cout<<"\nEnter element you want to search : "; + cin>>item; + ptr = top; + while( ptr != NULL) + { + if(item == ptr -> info) + { + cout<<"\nElement found at pos : "< link; + } + if(ptr == NULL) + cout<<"\nElement not found!"; + cout<<"\nWant to search any other element ?(y/n)..."; + cin>>ch; + } +} + +int main() +{ + int choice; + stak o; + while(1) + { + cout<<"\n\tMENU\n1.Push\n2.Pop \n3.Show\n4. Search\n5. Exit"; + cout<<"\nEnter your choice : "; + cin>>choice; + switch (choice) + { + case 1 : o.push(); + break; + case 2 : o.pop(); + break; + case 3 : o.show(); + break; + case 4 : o.search(); + break; + case 5 : exit(0); + default: cout<<"\nInvalid choice!"; + break; + } + } + return 0; +} + + diff --git a/data structures/stack/cpp/max-element.cpp b/data structures/stack/cpp/max-element.cpp new file mode 100644 index 000000000..65ef6a313 --- /dev/null +++ b/data structures/stack/cpp/max-element.cpp @@ -0,0 +1,33 @@ +#include +using namespace std; +int main() +{ + stacks1,s2; + s2.push(-1); + int n,i,q,x; + cin>>n; + for(i=1;i<=n;i++) + { + cin>>q; + if(q==1) + { + cin>>x; + s1.push(x); + if(x>=s2.top()) + s2.push(x); + } + else if(q==2) + { + if(s1.top()==s2.top()) + s2.pop(); + s1.pop(); + + } + else if(q==3){ + //int m=max(s1); + + cout< +{ + Stack min = new Stack<>(); + + /* SpecialStack's member method to insert an element to it. This method + makes sure that the min stack is also updated with appropriate minimum + values */ + void push(int x) + { + if(isEmpty() == true) + { + super.push(x); + min.push(x); + } + else + { + super.push(x); + int y = min.pop(); + min.push(y); + if(x < y) + min.push(x); + else + min.push(y); + } + } + + /* SpecialStack's member method to insert an element to it. This method + makes sure that the min stack is also updated with appropriate minimum + values */ + public Integer pop() + { + int x = super.pop(); + min.pop(); + return x; + } + + /* SpecialStack's member method to get minimum element from it. */ + int getMin() + { + int x = min.pop(); + min.push(x); + return x; + } + + /* Driver program to test SpecialStack methods */ + public static void main(String[] args) + { + SpecialStack s = new SpecialStack(); + s.push(10); + s.push(20); + s.push(30); + System.out.println(s.getMin()); + s.push(5); + System.out.println(s.getMin()); + } +} +// This code is contributed by Sumit Ghosh diff --git a/data structures/stack/java/stack.java b/data structures/stack/java/stack.java new file mode 100644 index 000000000..18af1141c --- /dev/null +++ b/data structures/stack/java/stack.java @@ -0,0 +1,57 @@ +import java.io.*; +import java.util.*; + +class Test +{ + // Pushing element on the top of the stack + static void stack_push(Stack stack) + { + for(int i = 0; i < 5; i++) + { + stack.push(i); + } + } + + // Popping element from the top of the stack + static void stack_pop(Stack stack) + { + System.out.println("Pop :"); + + for(int i = 0; i < 5; i++) + { + Integer y = (Integer) stack.pop(); + System.out.println(y); + } + } + + // Displaying element on the top of the stack + static void stack_peek(Stack stack) + { + Integer element = (Integer) stack.peek(); + System.out.println("Element on stack top : " + element); + } + + // Searching element in the stack + static void stack_search(Stack stack, int element) + { + Integer pos = (Integer) stack.search(element); + + if(pos == -1) + System.out.println("Element not found"); + else + System.out.println("Element is found at position " + pos); + } + + + public static void main (String[] args) + { + Stack stack = new Stack(); + + stack_push(stack); + stack_pop(stack); + stack_push(stack); + stack_peek(stack); + stack_search(stack, 2); + stack_search(stack, 6); + } +} \ No newline at end of file diff --git a/data structures/stack/javascript/stack.js b/data structures/stack/javascript/stack.js new file mode 100644 index 000000000..bb7216085 --- /dev/null +++ b/data structures/stack/javascript/stack.js @@ -0,0 +1,30 @@ +// Stack structure + +class Stack { + constructor() { + this.data = []; + } + + push(item) { + this.data.push(item); + } + + pop() { + return this.data.pop(); + } + + isEmpty() { + return this.data.length == 0; + } +} + +// Tests + +let stack = new Stack(); +console.assert(stack.isEmpty(), "Stack is empty"); +stack.push("First"); +stack.push("Second"); +stack.push("Third"); +console.assert(stack.pop(), "Popped element Third"); +stack.pop(); +console.assert(stack.isEmpty() == false, "Stack isn't empty"); diff --git a/data structures/stack/python/timeTravelStack.py b/data structures/stack/python/timeTravelStack.py new file mode 100644 index 000000000..76a2a9f84 --- /dev/null +++ b/data structures/stack/python/timeTravelStack.py @@ -0,0 +1,52 @@ +import unittest + +# a special kind of stack that remembers values +# that were popped off the stack, by storing them in +# a history list. It then can use these nodes in +# the history to restore previsouly popped values. +class TimeTravelStack(): + + def __init__(self): + self.list = [] + self.history = [] + + # pushs the given value onto the list + def push(self, x): + self.list.append(x) + + # pops a value from the list and push's it onto the history list + def pop(self): + lastPopped = self.list.pop() + self.history.append(lastPopped) + return lastPopped + + # pops a value from the history list and push's it back onto the main list + def restore(self): + lastPoppedHistory = self.history.pop() + self.list.append(lastPoppedHistory) + + +class TimeTravelStackTest(unittest.TestCase): + + # tests TimeTravelStack's push and pop method + def test_push_and_pop(self): + x = TimeTravelStack() + x.push(5) + x.push(6) + self.assertEqual(6, x.pop()) + + # tests TimeTravelStack's restore method + def test_restore(self): + x = TimeTravelStack() + x.push(7) + x.push(8) + x.pop() + x.restore() + self.assertEqual(x.pop(), 8) + + + +if __name__ == "__main__": + unittest.main() + + diff --git a/data structures/stack/scala/insert.scala b/data structures/stack/scala/insert.scala new file mode 100644 index 000000000..994245243 --- /dev/null +++ b/data structures/stack/scala/insert.scala @@ -0,0 +1,27 @@ +import scala.collection.mutable.Stack + +// Creating object +object GfG +{ + + // Main method + def main(args:Array[String]) + { + + var s = Stack[Int]() + + // pushing values + // one at a time + s.push(5) + s.push(1) + s.push(2) + println("s:" + s) + + var s2 = Stack[Int]() + + // pushing multiple values + s2.push(5,1,2) + println("s2:" + s2) + + } +} diff --git a/data structures/stack/scala/pop.scala b/data structures/stack/scala/pop.scala new file mode 100644 index 000000000..08413d7d7 --- /dev/null +++ b/data structures/stack/scala/pop.scala @@ -0,0 +1,25 @@ +import scala.collection.mutable.Stack + +// Creating object +object GfG +{ + + // Main method + def main(args:Array[String]) + { + + var s = Stack[Int]() + + s.push(5) + s.push(1) + s.push(2) + println(s) + + // pop element from + // top of the stack + + println("Popped:" + s.pop) + println("Popped:" + s.pop) + println("Popped:" + s.pop) + } +} diff --git a/data structures/stack/swift/stack.swift b/data structures/stack/swift/stack.swift new file mode 100644 index 000000000..d6810b074 --- /dev/null +++ b/data structures/stack/swift/stack.swift @@ -0,0 +1,29 @@ +// Stack structure + +class Stack { + private var data = [T]() + + func push(element: T) { + data.append(element) + } + + func pop() -> T? { + return data.popLast() + } + + var isEmpty: Bool { + return data.isEmpty + } + +} + +// Tests + +let stack = Stack() +assert(stack.isEmpty, "Stack is empty") +stack.push(element: "First") +stack.push(element: "Second") +stack.push(element: "Third") +assert(stack.pop() == "Third", "Popped element Third") +_ = stack.pop() +assert(stack.isEmpty == false, "Stack isn't empty") diff --git a/data structures/trie/c/AVL.c b/data structures/trie/c/AVL.c new file mode 100644 index 000000000..aa9bbf7ed --- /dev/null +++ b/data structures/trie/c/AVL.c @@ -0,0 +1,338 @@ +#include +#include + +struct node +{ + int data, height; + struct node *lc, *rc; +}; + +struct node* least(struct node* root) +{ + struct node* current = root; + if(current != NULL) + while(current->lc != NULL) + current = current->lc; + + return current; +} + +int height(struct node* root) +{ + if (root == NULL) + return 0; + return root->height; +} + +int max(int a, int b) +{ + if (a>= b) + return a; + return b; +} + +struct node* newnode(int data) +{ + struct node* root = (struct node*)malloc(sizeof(struct node)); + root->data = data; + root->lc = NULL; + root->rc = NULL; + root->height = 1; + return root; +} + + +struct node* rightrightZigZig(struct node* z) +{ + struct node* y = z->rc; + struct node* ylc = y->lc; + + // pointer changes. make z = rc of y and rc of y = lc of z + y->lc = z; + z->rc = ylc; + + // Updating the heights:- + + z->height = max(height(z->lc), height(z->rc)) + 1; + y->height = max(height(y->lc), height(y->rc)) + 1; + + + return y; +} +struct node* leftleftZigZig(struct node* z) +{ + struct node* y = z->lc; + struct node* yrc = y->rc; + + // pointer changes. make z = rc of y and rc of y = lc of z + y->rc = z; + z->lc = yrc; + + // Updating the heights:- + + z->height = max(height(z->lc), height(z->rc)) + 1; + y->height = max(height(y->lc), height(y->rc)) + 1; + + + return y; +} + +struct node* leftrightZigZag(struct node* z) +{ + // struct node* y = z->lc; + // struct node* x = y->rc; + // struct node* xlc = x->lc; + // struct node* xrc = x->rc; + + // // Pointer Changes. Right rotation on y, and left rotation on z. + // x->lc = y; + // y->rc = xlc; + // x->rc = z; + // z->lc = xrc; + + // //updating heights + + // x->height = max(height(x->lc), height(x->rc)) + 1; + // y->height = max(height(y->lc), height(y->rc)) + 1; + // z->height = max(height(z->lc), height(z->rc)) + 1; + + z->lc = rightrightZigZig(z->lc); + return leftleftZigZig(z); + +} + +struct node* rightleftZigZag(struct node* z) +{ + // struct node* y = z->rc; + // struct node* x = y->lc; + // struct node* xlc = x->lc; + // struct node* xrc = x->rc; + + // // Pointer Changes. Right rotation on y, and left rotation on z. + // x->rc = y; + // y->lc = xrc; + // x->lc = z; + // z->rc = xlc; + + // //updating heights + + // x->height = max(height(x->lc), height(x->rc)) + 1; + // y->height = max(height(y->lc), height(y->rc)) + 1; + // z->height = max(height(z->lc), height(z->rc)) + 1; + + z->rc = leftleftZigZig(z->rc); + return rightrightZigZig(z); + +} + +// int mod(int a) +// { +// if (a >= 0) +// return a; + +// else +// return -a; +// } +int getBalance(struct node *root) +{ + if (root == NULL) + return 0; + return height(root->lc) - height(root->rc); +} + +struct node* searchTree(struct node* root, int key) +{ + if (key == root->data) + return root; + else if(key > root->data) + return searchTree(root->rc, key); + else + return searchTree(root->lc, key); + return NULL; +} + +struct node* insertNode(struct node* root, int key) +{ + if (root == NULL) + return newnode(key); + if (key < root->data) + root->lc = insertNode(root->lc, key); + else if(key > root->data) + root->rc = insertNode(root->rc, key); + else //Impossible case as equal keys are not allowed + return root; + + // Steps in algo:- + // 1) Update the height of the current node + // 2) get the balance factor. + // 3) perform rotations if balance factor > 1 + + // 1) + root->height = max(height(root->lc), height(root->rc)) + 1; + + // 2) + int balance = getBalance(root); + + // 3 + //left left case + if(balance > 1 && key lc->data) + return leftleftZigZig(root); + if(balance < -1 && key > root->rc->data) + return rightrightZigZig(root); + if(balance > 1 && key > root->lc->data) + return leftrightZigZag(root); + if (balance < -1 && key < root->rc->data) + return rightleftZigZag(root); + + return root; + +} + +// The recursive code itself travels up and visits all the ancestors of the deleted node. +// 1) Perform the normal BST deletion. +// 2) The current node must be one of the ancestors of the deleted node. +// Update the height of the current node. +// 3) Get the balance factor (left subtree height – right subtree height) of the current node. +// 4) If balance factor is greater than 1, then the current node is unbalanced and we are either in Left Left case or Left Right case. +// To check whether it is Left Left case or Left Right case, get the balance factor of left subtree. +// If balance factor of the left subtree is greater than or equal to 0, then it is Left Left case, else Left Right case. +// 5) If balance factor is less than -1, then the current node is unbalanced and we are either in Right Right case or Right Left case. +// To check whether it is Right Right case or Right Left case, get the balance factor of right subtree. +// If the balance factor of the right subtree is smaller than or equal to 0, then it is Right Right case, else Right Left case. + + + +struct node* deleteNode(struct node* root, int key) +{ + if(root == NULL) + return root; + if (key < root->data) + root->lc = deleteNode(root->lc, key); + else if (key > root->data) + root->rc = deleteNode(root->rc, key); + else + { + // If temp is null, then make root null + // if temp is non null (one child) copy contents to root, and free temp. + if(root->lc == NULL) + { + struct node* temp = root->rc; + if(temp == NULL) + { + temp = root; + root = NULL; + } + else + *root = *temp; + free(temp); + } + else if(root->rc == NULL) + { + struct node* temp = root->lc; + *root = *temp; + free(temp); + } + + // Two child case!! + else + { + struct node* temp = root->rc; + temp = least(temp); + root->data = temp->data; + root->rc = deleteNode(root->rc, temp->data); + } + + } + //In case the entire tree gets deleted. + if (root == NULL) + return root; + + root->height = max(height(root->lc), height(root->rc)) + 1; + + int balance = getBalance(root); + + if (balance > 1 && getBalance(root->lc) >= 0) + root = leftleftZigZig(root); + if (balance > 1 && getBalance(root->lc)<0) + root = leftrightZigZag(root); + if (balance < -1 && getBalance(root->rc) <= 0) + root = rightrightZigZig(root); + if (balance < -1 && getBalance(root->rc) >0) + root = rightleftZigZag(root); + + return root; +} + +void printInorder(struct node* node) +{ + if (node == NULL) + return; + + /* first recur on left child */ + printInorder(node->lc); + + /* then print the data of node */ + printf("%d ", node->data); + + /* now recur on right child */ + printInorder(node->rc); +} + +void preorder(struct node* root) +{ + if (root != NULL) + { + printf("%d ", root->data); + preorder(root->lc); + preorder(root->rc); + } +} + +int main() +{ + struct node* root = NULL; + root = insertNode(root,9); + // preorder(root); + // printf("Success\n"); + root = insertNode(root,5); + // preorder(root); + // printf("Success\n"); + root = insertNode(root, 10); + // preorder(root); + // printf("Success\n"); + root = insertNode(root, 0); + // preorder(root); + // printf("Success\n"); + root = insertNode(root, 6); + // preorder(root); + // printf("Success\n"); + root = insertNode(root, 11); + // preorder(root); + // printf("Success\n"); + root = insertNode(root, -1); + // preorder(root); + // printf("Success\n"); + root = insertNode(root, 1); + root = insertNode(root, 2); + printf("preorder:-\n"); + preorder(root); + root = deleteNode(root, 10); + printf("\npreorder after deleting 10 is\n"); + preorder(root); + // searchTree(root, 82); + // printf("Node found. value = \n"); + // deleteNode(root, 50); + // printf("done first delete\n"); + // deleteNode(root, 65); + // printf("done second delete\n"); + // deleteNode(root, 76); + // printf("done third delete\n"); + // printInorder(root); + + // struct node* root = NULL; + // root=insertNode(root,10); + // root=insertNode(root,20); + // root=insertNode(root,15); + // preorder(root); + return 0; +} diff --git a/data structures/trie/c/BST.c b/data structures/trie/c/BST.c new file mode 100644 index 000000000..f03d48ce2 --- /dev/null +++ b/data structures/trie/c/BST.c @@ -0,0 +1,121 @@ +#include +#include + +struct node +{ + int data; + struct node *lc, *rc; +}; + +struct node* least(struct node* root) +{ + struct node* current = root; + if(current != NULL) + while(current->lc != NULL) + current = current->lc; + + return current; +} + +struct node* newnode(int data) +{ + struct node* root = (struct node*)malloc(sizeof(struct node)); + root->data = data; + root->lc = NULL; + root->rc = NULL; + return root; +} + +struct node* searchTree(struct node* root, int key) +{ + if (key == root->data) + return root; + else if(key > root->data) + return searchTree(root->rc, key); + else + return searchTree(root->lc, key); + return NULL; +} + +struct node* insertNode(struct node* root, int key) +{ + if (root == NULL) + return newnode(key); + if (key < root->data) + root->lc = insertNode(root->lc, key); + else if(key > root->data) + root->rc = insertNode(root->rc, key); //Impossible case + return root; +} + +struct node* deleteNode(struct node* root, int key) +{ + if(root == NULL) + return root; + if (key < root->data) + root->lc = deleteNode(root->lc, key); + else if (key > root->data) + root->rc = deleteNode(root->rc, key); + else + { + if(root->lc == NULL) + { + struct node* temp = root->rc; + free(root); + return temp; + } + else if(root->rc == NULL) + { + struct node* temp = root->lc; + free(root); + return temp; + } + else + { + struct node* temp = root->rc; + temp = least(temp); + root->data = temp->data; + root->rc = deleteNode(root->rc, temp->data); + } + } +} + +void printInorder(struct node* node) +{ + if (node == NULL) + return; + + /* first recur on left child */ + printInorder(node->lc); + + /* then print the data of node */ + printf("%d ", node->data); + + /* now recur on right child */ + printInorder(node->rc); +} + +int main() +{ + struct node* root = newnode(44); + insertNode(root, 17); + insertNode(root, 50); + insertNode(root, 32); + insertNode(root, 88); + insertNode(root, 28); + insertNode(root, 65); + insertNode(root, 97); + insertNode(root, 54); + insertNode(root, 82); + insertNode(root, 76); + struct node* val = searchTree(root, 82); + printf("Node found. value = %d\n", val->data); + deleteNode(root, 50); + printf("done first delete\n"); + deleteNode(root, 65); + printf("done second delete\n"); + deleteNode(root, 76); + printf("done third delete\n"); + printInorder(root); + return 0; +} \ No newline at end of file diff --git a/heaps/JavaScript/heap.js b/heaps/JavaScript/heap.js new file mode 100644 index 000000000..98796766a --- /dev/null +++ b/heaps/JavaScript/heap.js @@ -0,0 +1,69 @@ +class Heap { + constructor(compareFunc) { + this.values = [null]; + this.compareFunc = compareFunc || ((x, y) => x < y); + } + + get top() { + return this.values[1]; + } + + get count() { + return this.values.length - 1; + } + + get isEmpty() { + return this.count === 0; + } + + add(value) { + let index = this.values.length; + this.values.push(value); + + while (index > 1 && this.compareFunc(value, this.values[index >> 1])) { + this.values[index] = this.values[index >> 1]; + index >>= 1; + } + + this.values[index] = value; + } + + removeTop() { + const value = this.values[this.values.length - 1]; + this.values.pop(); + + if (!this.isEmpty) { + this._heapifyDown(1, value); + } + } + + _heapifyDown(index, value) { + while (index * 2 + 1 < this.values.length) { + const isFirstChildBetter = + this.compareFunc( + this.values[index * 2], + this.values[index * 2 + 1] + ); + + const smallerChildIndex = isFirstChildBetter ? + index * 2 : + index * 2 + 1; + if (this.compareFunc(this.values[smallerChildIndex], value)) { + this.values[index] = this.values[smallerChildIndex]; + index = smallerChildIndex; + } else { + break; + } + } + + if (index * 2 < this.values.length) { + const smallerChildIndex = index * 2; + if (this.compareFunc(this.values[smallerChildIndex], value)) { + this.values[index] = this.values[smallerChildIndex]; + index = smallerChildIndex; + } + } + + this.values[index] = value; + } +} diff --git a/heaps/heap-2.lisp b/heaps/heap-2.lisp new file mode 100644 index 000000000..7cc0f1241 --- /dev/null +++ b/heaps/heap-2.lisp @@ -0,0 +1,196 @@ +;;; An implementation of heap-2 from this article +;;; http://scholar.colorado.edu/cgi/viewcontent.cgi?article=1000&context=asen_facpapers + + +(defstruct heap2-element + ;; doubly linked list structure + back + fwd + ;; data + (bucket -1 :type integer) + distance + (in-S-p nil :type boolean) + (previous -1 :type integer) ;the index of the graph node + ;that comes before this + ;element on a shortest path + ;from the source + (this -1 :type integer)) ;The index of this element in the graph. + + +;;; The graph nodes will store their status internaly. Two fields will +;;; be added. One will hold the information of whther the node is in +;;; S, the other will hold a pointer to the heap node representing +;;; this graph node in the heap. If the latter is nil, then the node +;;; is not in the heap. + + +(defstruct heap2 + buckets ;the array of buckets + (start -1 :type integer) ;the index of the lowest bucket + l-min + l-max + (beta 0 :type integer)) + +(defstruct graph-node + (this -1 :type integer) + edge-weight) + + +(defun heap2-insert-head (heap he k) + (let ((old-head (aref (heap2-buckets heap) k))) + (when old-head ;inserting into empty list + (setf (heap2-element-back old-head) he)) + (setf (heap2-element-bucket he) k) + (setf (heap2-element-fwd he) old-head) + (setf (aref (heap2-buckets heap) k) he) + he)) + + +(defun heap2-delete-from-list (heap he) + "delete the given heap element from the list it is in. Returns the + modified he." + (let ((prev (heap2-element-back he)) + (next (heap2-element-fwd he))) + (when next ;if he is the last element, next is nil + (setf (heap2-element-back next) prev)) + (if prev ;if he is the first element, prev is nil + (setf (heap2-element-fwd prev) next) + (setf (aref (heap2-buckets heap) (heap2-element-bucket he)) next)) + (setf (heap2-element-fwd he) nil) + (setf (heap2-element-bucket he) -1) + (setf (heap2-element-back he) nil) + he)) + +(defun heap2-update-value (heap he new-distance previous) + "Update the distance in node v and change the heap + accordingly. `he` is a heap2-element and might yet have to be added + to the heap. `previous` is the node that was just added to S and is + a neighbour of the current node. Uses Alg. 4 from + http://scholar.colorado.edu/cgi/viewcontent.cgi?article=1000&context=asen_facpapers" + (let* ((l (heap2-l-min heap)) + (beta (heap2-beta heap)) + (k (mod (floor new-distance l) (1+ beta)))) + (setf (heap2-element-distance he) new-distance) + (setf (heap2-element-previous he) previous) + (if (>= (heap2-element-bucket he) 0) ;element is in the heap + (progn + (heap2-delete-from-list heap he) + (heap2-insert-head heap he k)) + (heap2-insert-head heap he k))) + nil) + +(defun heap2-pop-min (heap) + "Pop the node to be inserted into S from the heap." + (let* ((kf (mod (1- (heap2-start heap)) + (1+ (heap2-beta heap)))) + (k (do ((kc (mod (heap2-start heap) + (1+ (heap2-beta heap))) + (mod (1+ kc) + (1+ (heap2-beta heap))))) + ((or (= kc kf) (aref (heap2-buckets heap) kc)) + kc))) + (b (aref (heap2-buckets heap) k))) + (setf (heap2-start heap) k) + (when b ;not empty, b is the head of the list + (heap2-delete-from-list heap b)))) + +;;; dijkstra algorithm using heap 2 + +(defun edge-lengths (graph) + "get a list of all edge lengths for the given adjancency list + represented graph." + (apply #'nconc (map 'list (lambda (neighbours) + (mapcar #'graph-node-edge-weight neighbours)) + graph))) + + +(defun heap2-dijkstra (graph origin) + "returns an array of heap2-elements each with a calculated distance + from the origin and the node that comes on the shortest path before + the current node. thus they can be used to reconstruct the actual + shortest path from origin to given graph node in O(edges in path) + time. `graph` is an array of lists. the elements of each list are + graph-nodes. `origin is the index denoting the origin vertex in the + graph adjacency list." + (let* ((s (make-array (length graph) + :initial-contents (loop for i below (length graph) + collect (make-heap2-element :this i)))) + (edge-lengths (edge-lengths graph)) + (l-min (apply #'min edge-lengths)) + (l-max (apply #'max edge-lengths)) + (beta (ceiling l-max l-min)) + (heap (make-heap2 :buckets (make-array (1+ beta) :initial-element nil) + :beta beta + :l-min l-min + :l-max l-max + :start 0))) + (setf (heap2-element-distance (aref s origin)) 0) + (labels ((get-new-distance-and-ancestor + (node neighbour) + (let* ((p-he (aref s node)) + (n-he (aref s (graph-node-this neighbour))) + (new-distance + (+ (heap2-element-distance p-he) + (graph-node-edge-weight neighbour)))) + (if n-he + (let ((distance (heap2-element-distance n-he))) + (if distance + (if (< new-distance distance) + (values new-distance (heap2-element-this p-he)) + ;; if diatance is nil then it is effectively inf + (values distance (heap2-element-previous n-he))) + (values new-distance (heap2-element-this p-he)))) + (values new-distance (heap2-element-this p-he))))) + (update-node + (node) + (mapc (lambda (neighbour) + (multiple-value-bind (new-distance previous) + (get-new-distance-and-ancestor node neighbour) + (when (not (heap2-element-in-s-p + (aref s (graph-node-this neighbour)))) + (heap2-update-value heap (aref s (graph-node-this neighbour)) + new-distance + previous)))) + (aref graph node)))) + (setf (heap2-element-in-s-p (aref s origin)) t) + (update-node origin) + (do ((next-element (heap2-pop-min heap) (heap2-pop-min heap))) + ((not next-element) s) + (setf (heap2-element-in-s-p next-element) t) + (update-node (heap2-element-this next-element)))))) + + +(defvar test-graph (vector (list (make-graph-node :this 1 :edge-weight 1) + (make-graph-node :this 2 :edge-weight 4) + (make-graph-node :this 3 :edge-weight 2)) + (list (make-graph-node :this 2 :edge-weight 3) + (make-graph-node :this 3 :edge-weight 3)) + '() + (list (make-graph-node :this 2 :edge-weight 1)) + (list (make-graph-node :this 0 :edge-weight 5)))) + + +(defvar test-graph2 (vector (list (make-graph-node :this 1 :edge-weight 4) + (make-graph-node :this 2 :edge-weight 2.5) + (make-graph-node :this 3 :edge-weight 3) + (make-graph-node :this 5 :edge-weight 2)) + (list (make-graph-node :this 0 :edge-weight 1)) + (list (make-graph-node :this 4 :edge-weight 3.2)) + (list (make-graph-node :this 1 :edge-weight 1)) + (list (make-graph-node :this 3 :edge-weight 0.5) + (make-graph-node :this 0 :edge-weight 1)) + (list (make-graph-node :this 3 :edge-weight 0.5)))) + +(defun heap2-get-shortest-path (s node) + "s is a vector as returned by heqp2-dijksra, node is an integer + denoting a node of the graph" + (labels ((helper (node accum) + (let* ((current (aref s node)) + (previous (heap2-element-previous current)) + (is-solution (heap2-element-in-s-p current)) + (current-index (heap2-element-this current))) + (cond + ((not is-solution) nil) + ((= -1 previous) (cons current-index accum)) + (t (helper previous (cons current-index accum))))))) + (helper node '()))) diff --git a/heaps/priority queue/linklist_priority_que.c.txt b/heaps/priority queue/linklist_priority_que.c.txt new file mode 100644 index 000000000..28faa390c --- /dev/null +++ b/heaps/priority queue/linklist_priority_que.c.txt @@ -0,0 +1,99 @@ + +// C code to implement Priority Queue +// using Linked List +#include +#include + +// Node +typedef struct node { + int data; + + // Lower values indicate higher priority + int priority; + + struct node* next; + +} Node; + +// Function to Create A New Node +Node* newNode(int d, int p) +{ + Node* temp = (Node*)malloc(sizeof(Node)); + temp->data = d; + temp->priority = p; + temp->next = NULL; + + return temp; +} + +// Return the value at head +int peek(Node** head) +{ + return (*head)->data; +} + +// Removes the element with the +// highest priority form the list +void pop(Node** head) +{ + Node* temp = *head; + (*head) = (*head)->next; + free(temp); +} + +// Function to push according to priority +void push(Node** head, int d, int p) +{ + Node* start = (*head); + + // Create new Node + Node* temp = newNode(d, p); + + // Special Case: The head of list has lesser + // priority than new node. So insert new + // node before head node and change head node. + if ((*head)->priority > p) { + + // Insert New Node before head + temp->next = *head; + (*head) = temp; + } + else { + + // Traverse the list and find a + // position to insert new node + while (start->next != NULL && + start->next->priority < p) { + start = start->next; + } + + // Either at the ends of the list + // or at required position + temp->next = start->next; + start->next = temp; + } +} + +// Function to check is list is empty +int isEmpty(Node** head) +{ + return (*head) == NULL; +} + +// Driver code +int main() +{ + // Create a Priority Queue + // 7->4->5->6 + Node* pq = newNode(4, 1); + push(&pq, 5, 2); + push(&pq, 6, 3); + push(&pq, 7, 0); + + while (!isEmpty(&pq)) { + printf("%d ", peek(&pq)); + pop(&pq); + } + + return 0; +} \ No newline at end of file diff --git a/heaps/priority queue/priority_queue.cpp b/heaps/priority queue/priority_queue.cpp new file mode 100644 index 000000000..1c8f7b16e --- /dev/null +++ b/heaps/priority queue/priority_queue.cpp @@ -0,0 +1,105 @@ +// C++ code to implement Priority Queue +// using Linked List +#include +using namespace std; + +// Node +typedef struct node +{ + int data; + + // Lower values indicate + // higher priority + int priority; + + struct node* next; + +} Node; + +// Function to create a new node +Node* newNode(int d, int p) +{ + Node* temp = (Node*)malloc(sizeof(Node)); + temp->data = d; + temp->priority = p; + temp->next = NULL; + + return temp; +} + +// Return the value at head +int peek(Node** head) +{ + return (*head)->data; +} + +// Removes the element with the +// highest priority form the list +void pop(Node** head) +{ + Node* temp = *head; + (*head) = (*head)->next; + free(temp); +} + +// Function to push according to priority +void push(Node** head, int d, int p) +{ + Node* start = (*head); + + // Create new Node + Node* temp = newNode(d, p); + + // Special Case: The head of list has + // lesser priority than new node. So + // insert newnode before head node + // and change head node. + if ((*head)->priority > p) + { + + // Insert New Node before head + temp->next = *head; + (*head) = temp; + } + else + { + + // Traverse the list and find a + // position to insert new node + while (start->next != NULL && + start->next->priority < p) + { + start = start->next; + } + + // Either at the ends of the list + // or at required position + temp->next = start->next; + start->next = temp; + } +} + +// Function to check is list is empty +int isEmpty(Node** head) +{ + return (*head) == NULL; +} + +// Driver code +int main() +{ + + // Create a Priority Queue + // 7->4->5->6 + Node* pq = newNode(4, 1); + push(&pq, 5, 2); + push(&pq, 6, 3); + push(&pq, 7, 0); + + while (!isEmpty(&pq)) + { + cout << " " << peek(&pq); + pop(&pq); + } + return 0; +} diff --git a/heaps/priority queue/priority_queue.java b/heaps/priority queue/priority_queue.java new file mode 100644 index 000000000..e8a1ae361 --- /dev/null +++ b/heaps/priority queue/priority_queue.java @@ -0,0 +1,104 @@ +// Java code to implement Priority Queue +// using Linked List +import java.util.* ; + +class Solution +{ + + +// Node + static class Node { + int data; + + // Lower values indicate higher priority + int priority; + + Node next; + +} + +static Node node = new Node(); + +// Function to Create A New Node +static Node newNode(int d, int p) +{ + Node temp = new Node(); + temp.data = d; + temp.priority = p; + temp.next = null; + + return temp; +} + +// Return the value at head +static int peek(Node head) +{ + return (head).data; +} + +// Removes the element with the +// highest priority form the list +static Node pop(Node head) +{ + Node temp = head; + (head) = (head).next; + return head; +} + +// Function to push according to priority +static Node push(Node head, int d, int p) +{ + Node start = (head); + + // Create new Node + Node temp = newNode(d, p); + + // Special Case: The head of list has lesser + // priority than new node. So insert new + // node before head node and change head node. + if ((head).priority > p) { + + // Insert New Node before head + temp.next = head; + (head) = temp; + } + else { + + // Traverse the list and find a + // position to insert new node + while (start.next != null && + start.next.priority < p) { + start = start.next; + } + + // Either at the ends of the list + // or at required position + temp.next = start.next; + start.next = temp; + } + return head; +} + +// Function to check is list is empty +static int isEmpty(Node head) +{ + return ((head) == null)?1:0; +} + +// Driver code +public static void main(String args[]) +{ + // Create a Priority Queue + // 7.4.5.6 + Node pq = newNode(4, 1); + pq =push(pq, 5, 2); + pq =push(pq, 6, 3); + pq =push(pq, 7, 0); + + while (isEmpty(pq)==0) { + System.out.printf("%d ", peek(pq)); + pq=pop(pq); + } + +} +} diff --git a/logistic-regression/README.md b/logistic-regression/README.md new file mode 100644 index 000000000..8768f6c4c --- /dev/null +++ b/logistic-regression/README.md @@ -0,0 +1,3 @@ +Logistic regression + +In statistics, the logistic model (or logit model) is a widely used statistical model that, in its basic form, uses a logistic function to model a binary dependent variable; many more complex extensions exist. In regression analysis, logistic regression (or logit regression) is estimating the parameters of a logistic model; it is a form of binomial regression. Mathematically, a binary logistic model has a dependent variable with two possible values, such as pass/fail, win/lose, alive/dead or healthy/sick; these are represented by an indicator variable, where the two values are labeled "0" and "1". In the logistic model, the log-odds (the logarithm of the odds) for the value labeled "1" is a linear combination of one or more independent variables ("predictors"); the independent variables can each be a binary variable (two classes, coded by an indicator variable) or a continuous variable (any real value). The corresponding probability of the value labeled "1" can vary between 0 (certainly the value "0") and 1 (certainly the value "1"), hence the labeling; the function that converts log-odds to probability is the logistic function, hence the name. The unit of measurement for the log-odds scale is called a logit, from logistic unit, hence the alternative names. Analogous models with a different sigmoid function instead of the logistic function can also be used, such as the probit model; the defining characteristic of the logistic model is that increasing one of the independent variables multiplicatively scales the odds of the given outcome at a constant rate, with each dependent variable having its own parameter; for a binary independent variable this generalizes the odds ratio. diff --git a/logistic-regression/logistic-reg-scala.txt b/logistic-regression/logistic-reg-scala.txt new file mode 100644 index 000000000..4809a2da1 --- /dev/null +++ b/logistic-regression/logistic-reg-scala.txt @@ -0,0 +1,144 @@ + +// I took reference from here: https://towardsdatascience.com/building-a-logistic-regression-in-python-step-by-step-becd4d56c9c8 +//The dataset comes from the UCI Machine Learning repository, and it is related to direct marketing campaigns (phone calls) of a Portuguese +//banking institution. The classification goal is to predict whether the client will subscribe (1/0) to a term deposit (variable y). The dataset +//can be downloaded from here: https://raw.githubusercontent.com/madmashup/targeted-marketing-predictive-engine/master/banking.csv + +> import org.apache.log4j. + +> Logger.getLogger("org").setLevel(Level.ERROR) + +//reading data from csv +> val data = spark.read.format("csv").option("header", "true").option("inferschema", "true").load("/home/arham/Documents/spark-pro/banking.csv") + +//getting only the usefull columns for our model +//why we use these columns? find it here https://towardsdatascience.com/building-a-logistic-regression-in-python-step-by-step-becd4d56c9c8#a448 +> val needed_cols = (data.select(data("y").as("label"), $"job",$"marital",$"education",$"default",$"housing",$"loan",$"contact",$"month",$"day_of_week",$"poutcome")) + +//getting number of records +> needed_cols.count() +//res17: Long = 41188 + +> needed_cols.show(20) + +//drop all null rows +> val reduced_null_value_data = needed_cols.na.drop() + +//percentage of class 0 or not taking subscription +scala> (reduced_null_value_data.where("label == 0").count()*100)/reduced_null_value_data.count() +//res43: Long = 88 + +//percentage of class 1 or taking subscription +> (reduced_null_value_data.where("label == 1").count()*100)/reduced_null_value_data.count() +//res44: Long = 11 + +> import org.apache.spark.ml.feature.{OneHotEncoder, StringIndexer} + +// indexing the column values find more about it here: https://spark.apache.org/docs/latest/ml-features.html#stringindexer +> val job_indexer = new StringIndexer().setInputCol("job").setOutputCol("job_index").fit(reduced_null_value_data) + +> val edu_indexer = new StringIndexer().setInputCol("education").setOutputCol("education_index").fit(reduced_null_value_data) + +> val marital_indexer = new StringIndexer().setInputCol("marital").setOutputCol("marital_index").fit(reduced_null_value_data) + +> val def_indexer = new StringIndexer().setInputCol("default").setOutputCol("default_index").fit(reduced_null_value_data) + +> val housing_indexer = new StringIndexer().setInputCol("housing").setOutputCol("housing_index").fit(reduced_null_value_data) + +> val loan_indexer = new StringIndexer().setInputCol("loan").setOutputCol("loan_index").fit(reduced_null_value_data) + +> val contact_indexer = new StringIndexer().setInputCol("contact").setOutputCol("contact_index").fit(reduced_null_value_data) + +> val month_indexer = new StringIndexer().setInputCol("month").setOutputCol("month_index").fit(reduced_null_value_data) + +> val day_of_week_indexer = new StringIndexer().setInputCol("day_of_week").setOutputCol("day_of_week_index").fit(reduced_null_value_data) + +> val poutcome_indexer = new StringIndexer().setInputCol("poutcome").setOutputCol("poutcome_index").fit(reduced_null_value_data) + + +// Encoding the column values find more about it here: https://spark.apache.org/docs/2.1.0/ml-features.html#onehotencoder +> val edu_vector = new OneHotEncoder().setInputCol("education_index").setOutputCol("education_vector") + +> val marital_vector = new OneHotEncoder().setInputCol("marital_index").setOutputCol("marital_vector") + +> val job_vector = new OneHotEncoder().setInputCol("job_index").setOutputCol("job_vector") + +> val def_vector = new OneHotEncoder().setInputCol("default_index").setOutputCol("default_vector") + +> val housing_vector = new OneHotEncoder().setInputCol("housing_index").setOutputCol("housing_vector") + +> val loan_vector = new OneHotEncoder().setInputCol("loan_index").setOutputCol("loan_vector") + +> val contact_vector = new OneHotEncoder().setInputCol("contact_index").setOutputCol("contact_vector") + +> val month_vector = new OneHotEncoder().setInputCol("month_index").setOutputCol("month_vector") + +> val day_of_week_vector = new OneHotEncoder().setInputCol("day_of_week_index").setOutputCol("day_of_week_vector") + +> val poutcome_vector = new OneHotEncoder().setInputCol("poutcome_index").setOutputCol("poutcome_vector") + +> import org.apache.spark.ml.feature.{VectorAssembler, VectorIndexer} + +// combining all feature columns find more here: https://spark.apache.org/docs/2.1.0/ml-features.html#vectorassembler +> val assembler = newVectorAssembler().setInputCols(Array("job_vector","marital_vector","education_vector","default_vector","housing_vector","loan_vector","contact_vector","month_vector","day_of_week_vector","poutcome_vector")).setOutputCol("features") + +//splitting data with ratio 70:30 - training:testing +> val Array(training, testing) = reduced_null_value_data.randomSplit(Array(0.7, 0.3), seed=10) + +> import org.apache.spark.ml.Pipeline + +> import org.apache.spark.ml.classification.LogisticRegression + +> val log_reg = new LogisticRegression() + +//executing all through a pipeline +> val pipeline = new Pipeline().setStages(Array(job_indexer, marital_indexer, edu_indexer, def_indexer, housing_indexer, loan_indexer, contact_indexer, month_indexer, day_of_week_indexer, poutcome_indexer, job_vector, marital_vector, edu_vector, def_vector, housing_vector, loan_vector, contact_vector, month_vector, day_of_week_vector, poutcome_vector, assembler, log_reg)) + +//training +> val model = pipeline.fit(training) + +//testing +> val result = model.transform(testing) + +////////////////// +//Model Evaluation + +> result.printSchema + +> import org.apache.spark.mllib.evaluation.MulticlassMetrics + +// getting prediction and label from result and converting to rdd for Evaluation (because MulticlassMetrics need rdd and only available in mllib +//find more here: https://spark.apache.org/docs/2.3.0/mllib-evaluation-metrics.html#multiclass-classification) +> val predAndLabel = result.select($"prediction", $"label").as[(Double, Double)].rdd + +> val matrics = new MulticlassMetrics(predAndLabel) + +// getting accuracy +> matrics.accuracy +res11: Double = 0.8967916189229006 + +//getting confusion matrix +//it truly predicted 10712 records for label 0/not taking subscription +//and truly predicted 245 records for label 1/taking subscription +//131 wrong predictions for label 0/not taking subscription +//1130 wrong predictions for label 1/taking subscription +> println(matrics.confusionMatrix) +// predicted 0 predicted 1 +//actualy 0: 10712.0 131.0 +//actualy 1: 1130.0 245.0 + +//percentage of class 0 or not taking subscription(training dataset) +> (training.where("label == 0").count()*100)/training.count() +//res47: Long = 88 + +//percentage of class 1 or taking subscription (training dataset) +> (training.where("label == 1").count()*100)/training.count() +//res48: Long = 11 + +//percentage of class 0 or not taking subscription (testing dataset) +> (testing.where("label == 0").count()*100)/testing.count() +//res38: Long = 88 + +//percentage of class 1 or taking subscription (testing dataset) +> (testing.where("label == 1").count()*100)/testing.count() +//res39: Long = 11