• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to check where x falls?

Engaged ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Hi,

 

How to check where x falls?

 

check(116);

function check(x) {
	return 1+(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643);
}

 

Regards,

Sumit

-Sumit
TOPICS
Scripting

Views

1.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 4 Correct answers

Community Expert , Nov 22, 2021 Nov 22, 2021

Hi @SumitKumar,

I looked into the code and as @Peter Kahrel mentioneed the return value for 

PAGE_TO_SECTION(320) is 11575 and not 75 as you mentioned in the other post. Now as regards to what the following code snippet does
const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];
const PAGE_TO_SECTION = (function(/*uint[]&*/a,  n,s,i)
// -------------------------------------
// Return the func that converts a page number into a
// section number (1..N) depending o
...

Votes

Translate

Translate
Participant , Nov 23, 2021 Nov 23, 2021

If we need more than 12k checks, then no optimization is required, but I think we can speed up the script execution.
For this we need to create an object that already has a chapter number for each page.

 

#targetengine 'check chapter'

var LIST_OF_PAGES = {}
main()

function main(){

	const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]

	function create(from,to,chapter){
		for(var i = from; i < to; i++){
			LIST_OF_PAGES[i] = chapter
		}
	}
	
	for(var i = 0; i < R
...

Votes

Translate

Translate
Participant , Nov 23, 2021 Nov 23, 2021

Yesterday I had a lot of work, I suspected that I was wrong, but I could not understand what, today I understood))
Here one script is enough, for this we need to check the variable LIST_OF_PAGES

 

#targetengine 'check chapter'

if(typeof LIST_OF_PAGES == 'undefined'){
	var LIST_OF_PAGES = {}
	main()
	get()
}
else{get()}

function main(){

	const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]

	function create(from,to,chapter){
		for(var i = from; i < to; i++){
			L
...

Votes

Translate

Translate
Guide , Nov 25, 2021 Nov 25, 2021

Hi @SumitKumar 

 

No procedural approach can beat @SychevKA's method, since it is based on a pre-processed, full mapping of page numbers into section indices. Its object `LIST_OF_PAGES` already contains the set of all possible page numbers, so that `LIST_OF_PAGES[anyPage]` instantly returns the corresponding section number. (By instantly, I mean something like 2-3 µs on any decent system.)

 

Hence this is without doubt the most efficient approach. Even a highly fine-tuned binary algorithm won't run

...

Votes

Translate

Translate
Community Expert ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Can you explain the problem further? You want to return the number that x exceeds in the set? If so something like this:

 

var nums = [41, 73, 113, 147, 181, 213]; 

for (var i = 0; i < nums.length; i++) { 

    if (x >nums[i]) return nums[i];

}

return nums.pop();

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Hi Brian,

 

Thank you for your response.

Actually I don't want to use loop.

Basically I want to check where number falls before?

Input output ex: 

5 => 1

109 => 3

113 => 4

 

Regards,

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 30, 2021 Oct 30, 2021

Copy link to clipboard

Copied

Don't see any way out of using a loop. You'll need to return the iterator (i) to achieve that output and you'll need to examine each 'less than' element of the array. Still runs in worst case O(n)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Oct 31, 2021 Oct 31, 2021

Copy link to clipboard

Copied

Thank you.

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Nov 01, 2021 Nov 01, 2021

Copy link to clipboard

Copied

Try this :

alert (check(536));
//=============================
function check(y){
    var number = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];
    number = number.sort(function(a, b){return a - b;});
    if(y < number[number.length-1]){
        return true;
        }
    return false;
    }

Best

Sunil

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 19, 2021 Nov 19, 2021

Copy link to clipboard

Copied

Thanks Sunil but this is not my requirements.

 

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 21, 2021 Nov 21, 2021

Copy link to clipboard

Copied

Actually I don't want to use loop.

That's like "I want to nail this to the wall but I don't want to use a hammer."

 

return 1+(x>41,73, . . .

 

Where did you find this statement?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 21, 2021 Nov 21, 2021

Copy link to clipboard

Copied

Thank you Peter for your response and I like your statement

> "I want to nail this to the wall but I don't want to use a hammer.".

 

> Where did you find this statement?

I find it from here. Specially check this line 

 

 

    return Function('x', 'return '+s);

 

 

Earlier the function name "PAGE_TO_SECTION(320)" return correct value but now all the time return constant value whatever is the input no matter. I don't know what is wrong but something happened wrong during forum transition 2 years ago.

 

Regards,

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

quote

I find it from here.

 

that is an obfuscated code in which it seems to me the author himself will get lost. and look carefully, there is a loop in it.

 

quote

Earlier the function name "PAGE_TO_SECTION(320)" return correct value but now all the time return constant value whatever is the input no matter. I don't know what is wrong but something happened wrong during forum transition 2 years ago.

 

maybe your xml has changed

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Hi SychevKA,

 

Anonymous function return below function.

 

function anonymous(x) {
	return 1+(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)+
	(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)
}

 

Above code should return page number to section as per @Marc Autret .

// -------------------------------------
// Return the func that converts a page number to a
// section number (1..N) depending on RANGES and no matter xml changed or not.
// E.g. PAGE_TO_SECTION(320) => 9

Regards,

 

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

This code is made hard to read and does not do what you expect.

 

The value of (a,b,c,d,e,f...,z) is just z and all of a,b,c,d... have no effect on the result.

So

1+(x>41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643)

is 1+643 is 644.

There is no clever magic or side effect, just junk to confuse the reader. And there is no such code in the page you linked.

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Dear @Test Screen Name ,

 

Did you see original post?

 

 

const HREF_PATTERN = "M%1_BERK9695_07_SE_C%1.xhtml#page%2";
const RANGES = [41, 73, 113, 147, 181, 213, 255, 291, 333, 365, 405, 435, 467, 505, 535, 567, 607, 643];
const PAGE_TO_SECTION = (function (/*uint[]&*/a, n, s, i)
// -------------------------------------
// Return the func that converts a page number into a
// section number (1..N) depending on RANGES.
// E.g. PAGE_TO_SECTION(320) => 9
{
    for (n = a.length, s = '1', i = -1; ++i < n; s += '+(x>' + a + ')');
    return Function('x', 'return ' + s);
})(RANGES);

 

 

Regards,
-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

I saw. There is no similarity.

[a,b,c,d,e,...z] creates an array with those elements

(a,b,c,d,e,...z) returns z

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Thankk you.

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Sumit -- The code snippet you quoted return 11575, so clearly there's something wrong. The snippet does use a loop, by the way (for n = a.length. . .). And how you arrive at the code you proposed (your function check()) from Marc's code is not entirely clear to me.

 

What you're after is really very straightforward, a simple while loop returns the section number:

const RANGES = [0, 41, 73, 113, 147, 181, 213, 255, 291, 333, 365, 405, 435, 467, 505, 535, 567, 607, 643];

function check (folio) {
  var n = 0;
  while (n < RANGES.length && folio >= RANGES[n]) {
    n += 1;
  }
  return n;
}

check (320);

Peter

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Thank you Peter.

 

Yes there is also loop but RANGES.length times only.

At the index pages there are 12,000 page numbers appearing and if I use while loop it will loop morethan 1 lac times and it is slower.

My requirement is to add argument as page number and get the chapter number.

Chapter 1 --> 001-041

Chapter 2 --> 042-073

Chapter 3 --> 074-113

Chapter 4 --> 114-147

Chapter 5 --> 148-181

Chapter 6 --> 182-213

Chapter 7 --> 214-255

Chapter 8 --> 256-291

Chapter 9 --> 292-333

Chapter 10 --> 334-365

Chapter 11 --> 366-405

Chapter 12 --> 406-435

Chapter 13 --> 436-467

Chapter 14 --> 468-505

Chapter 15 --> 506-535

Chapter 16 --> 536-567

Chapter 17 --> 568-607

Chapter 18 --> 608-643

 

that's why I use below code but this function return constant value all the times.

 

PAGE_TO_SECTION(320) // return 9

 

 

So I just want to understand below code only.

const __ = $.global.localize;
const HREF_PATTERN = "M%1_BERK9695_07_SE_C%1.xhtml";
const RANGES = [41, 73, 113, 147, 181, 213, 255, 291, 333, 365, 405, 435, 467, 505, 535, 567, 607, 643];
const PAGE_TO_SECTION = (function (/*uint[]&*/a, n, s, i){
    for (n = a.length, s = '1', i = -1; ++i < n; s += '+(x>' + a + ')');
    return Function('x', 'return ' + s);
})(RANGES);

var sectionNumber = PAGE_TO_SECTION(320)// => 9
result = __(HREF_PATTERN, sectionNumber);

Regards,

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

I understand what you're after. I can't help you with understanding Marc's code, you'll have to ask him.

 

At the index pages there are 12,000 page numbers appearing and if I use while loop it will loop morethan 1 lac  [?] times and it is slower.

 

No: if you check 12,000 pages, Marc's for-loop iterates through the RANGES array 12,000 times, same as my code. The difference is that Marc uses a for-loop, I use a while-loop.

 

By the way, in (your version of) Marc's code, PAGE_TO_SECTION(320) reurns 11575, not 9.

 

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Thank you.

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

If you have to find an index into an array of 10000 items which define ranges, you need a loop. Even if there is a clever trick like using "sort" it will contain many loops and be even slower.

 

If I had to solve this problem, which might take on average 5000 loops, I would spend a few days coding a binary search, which would reduce it to a maximum 14 loops per search. This is not simple coding.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Thank you @Test Screen Name 

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 22, 2021 Nov 22, 2021

Copy link to clipboard

Copied

Hi @SumitKumar,

I looked into the code and as @Peter Kahrel mentioneed the return value for 

PAGE_TO_SECTION(320) is 11575 and not 75 as you mentioned in the other post. Now as regards to what the following code snippet does
const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];
const PAGE_TO_SECTION = (function(/*uint[]&*/a,  n,s,i)
// -------------------------------------
// Return the func that converts a page number into a
// section number (1..N) depending on RANGES.
// E.g. PAGE_TO_SECTION(320) => 9
{
    for( n=a.length, s='1', i=-1 ; ++i < n ; s+='+(x>'+a+')' );
    return Function('x', 'return '+s);
})(RANGES);

So the code basically creates an anonymous function that returns the value of the following expression

1+(x>41)+(x>73)+(x>113)+(x>147)+(x>181)+(x>213)+(x>255)+(x>291)+(x>333)+(x>365)+(x>405)+(x>435)+(x>467)+(x>505)+(x>535)+(x>567)+(x>607)+(x>643)

So what this does is, it checks if the passed in value is greater with each of the element on the base array(sorted) and keeps adding the return value, the return value will be 1 till the argument is greater and 0 afterwards. This explains why 320 would give a result as 9.

Now why do we get 11575 as the result and not 9 that is because the code is incorrect(not written incorrect but fudged up by migration to the new forum platform). The correct code would be as follows

const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643];
const PAGE_TO_SECTION = (function(/*uint[]&*/a,  n,s,i)
// -------------------------------------
// Return the func that converts a page number into a
// section number (1..N) depending on RANGES.
// E.g. PAGE_TO_SECTION(320) => 9
{
    for( n=a.length, s='1', i=-1 ; ++i < n ; s+='+(x>'+a[i]+')' );
    return Function('x', 'return '+s);
})(RANGES);

Now the code should seem quite understandable and not cryptic. So the loop has been used here as well albeit just for one pass of the array and for each search, henceforth its just a long list of comparisons that are executed. To me this looks like a good idea to speed up things. I am not sure what happens when the input array is really long like the 12000 entry you mentioned, woud like comments on that from @Test Screen Name and @Peter Kahrel, if they have ever played around with such an idea and would this, for me binary search looks more palatable.

-Manan

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

Thanks for the correction and the explanation, Manan. But the function doesn't look through a 12,000-element array. There are ~12,000 page numbers, so Marc's function executes 12,000 times. It's true though that the for-loop in Marc's function executes just once, which is very clever.

 

Overall, Marc's function outperforms mine. There is an interesting difference: in lower page numbers my function is quicker, whereas with higher page numbers, Marc's becomes much quicker. The reason must be that with low page numbers my function iterates the RANGES array just a couple of times and Marc's function suffers from the overhead of calling the inner function and its action (coercing the booleans to numbers and adding up the zeros and ones).

 

The book has somewhere between 650 and 700 pages, and there are 12,000 page references to check. The tipping point between Marc's and my function is around 250, so Marc's function wins in this job, hands-down probably. (Though we're talking milliseconds here -- either function would have done the job thousands of times while I was writing this message.)

 

A binary function would not work in this case I don't think.

 

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

If we need more than 12k checks, then no optimization is required, but I think we can speed up the script execution.
For this we need to create an object that already has a chapter number for each page.

 

#targetengine 'check chapter'

var LIST_OF_PAGES = {}
main()

function main(){

	const RANGES = [41,73,113,147,181,213,255,291,333,365,405,435,467,505,535,567,607,643]

	function create(from,to,chapter){
		for(var i = from; i < to; i++){
			LIST_OF_PAGES[i] = chapter
		}
	}
	
	for(var i = 0; i < RANGES.length; i++){
		var chapter = 'chapter '+(i+1)
		create(RANGES[i],RANGES[i+1],chapter)
	}

	if(RANGES[0] > 1){create(0,RANGES[0],0)}
	LIST_OF_PAGES['last'] = chapter
}

 

Now we have a chapter without compare.

 

#targetengine 'check chapter'

function get_rand(min,max){
	return Math.floor(Math.random()*(max-min))+min
}

var check = {}
for(var i = 0; i < 10; i++){
	var page = get_rand(1,700)
	
	// get a chapter without compare
	var chapter = LIST_OF_PAGES[page]
	if(typeof chapter == 'undefined'){check[page] = LIST_OF_PAGES['last']}
	else{check[page] = chapter}
}

var show = []
for(var k in check){
	show.push('\n'+k+'->'+check[k])
}

alert(show)

 

Notice there are two different scripts here. Until you restart the InDesign, you can run the second script as many times as you like and get the result without compare.

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 23, 2021 Nov 23, 2021

Copy link to clipboard

Copied

Thank you @SychevKA ,

 

This is the correct way to use minimum loop, around 650 loop.

But I was thinking that should I map multiple pages with same value that's why I did not use this approach.

 

Regards,

-Sumit

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines